-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDMST.cpp
More file actions
135 lines (130 loc) · 3.53 KB
/
DMST.cpp
File metadata and controls
135 lines (130 loc) · 3.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Directed MST
/*
* Minimum cost Arborescene
* Algorithm : Chu-liu-edmonds algorithm
* Order: O( V*E )
* Note: root must be in vertex 0
*/
#include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
using namespace std;
#define MAX_V 1007
#define pb push_back
struct EDGE{
long v,c;
bool InTr;
EDGE( long v,long c,bool InTr = false )
{
this->v = v;
this->c = c;
this->InTr = InTr;
}
};
typedef vector<EDGE> VE;
long nV,nE; // number of vertices and edges in initial
long Visit[MAX_V+7],TRUE; // used in dfs to check for visit
bool InStk[MAX_V+7]; // used in dfs to check visted vertices is in recursive call
long Par[MAX_V+7]; // parent vertices in dfs
long TotV; // to count number of vertices in dfs call
long nG; // number of grp
long Grp[MAX_V+7]; // grp in dex oa vertice used in cycle contraction in DMST
/* to set all the vertices in a cycle in same grp */
void SetGrp( long u,long v,long n )
{
Grp[v] = n;
if( u==v ) return;
SetGrp( u,Par[v],n );
}
/* dfs to to check in graph */
void Dfs( vector< VE > &Edge , long u , bool ChkTr = true )
{
Visit[u] = TRUE;
InStk[u] = true;
TotV++;
if( u==0 ) Grp[u] = nG++;
else Grp[u] = -1;
long i;
for( i=0;i<Edge[u].size();i++){
long v = Edge[u][i].v;
if( ChkTr && Edge[u][i].InTr == false ) continue;
if( InStk[v] ) SetGrp( v,u,nG++ );
else if( Visit[v]!=TRUE ){
Par[v] = u;
Dfs( Edge,v,ChkTr );
}
}
if( Grp[u]==-1 ) Grp[u] = nG++;
InStk[u] = false;
}
/* this return cost of DMST
should be call if arborescne
is possible */
long DMST( vector< VE > &Edge )
{
long N = Edge.size();
vector<long> MU( N,-1 );
vector<long> MI( N );
long u,v,i,MinCost = 0;
for( u=0;u<N;u++){
for( i=0;i<Edge[u].size();i++){
v = Edge[u][i].v;
if( v==0 ) continue;
if( MU[v]==-1 || Edge[ MU[v] ][ MI[v] ].c > Edge[u][i].c ){
if( MU[v]!=-1 ){
MinCost -= Edge[ MU[v] ][ MI[v] ].c;
Edge[ MU[v] ][ MI[v] ].InTr = false;
}
MU[v] = u;
MI[v] = i;
MinCost += Edge[u][i].c;
Edge[u][i].InTr = true;
}
}
}
/* termination condition */
if( N==2 ) return Edge[ MU[1] ][ MI[1] ].c;
TotV = 0;
nG = 0;
TRUE++;
Dfs( Edge,0 );
/* to check is any cycle created
if all vertice can be reachable
from root 0
*/
if( TotV==N ) return MinCost;
for( i=0;i<N;i++){
if( Visit[i]==TRUE ) continue;
Dfs( Edge,i );
}
/* new compressed graph is creating */
vector< VE > TmpE( nG );
for( u=0;u<N;u++){
for( i=0;i<Edge[u].size();i++){
long v = Edge[u][i].v;
if( v==0 ) continue;
if( Grp[u]==Grp[v] ) continue;
TmpE[ Grp[u]].pb( EDGE( Grp[v] , Edge[u][i].c - Edge[ MU[v] ][ MI[v] ].c ) );
}
}
Edge.clear();
return MinCost + DMST( TmpE );
}
int main( void )
{
long i,u,v,c,Icase,k = 0;
scanf("%ld%ld",&nV,&nE );
vector< VE > Edge( nV );
for( i=1;i<=nE;i++){
scanf("%ld%ld%ld",&u,&v,&c );
Edge[u].pb( EDGE( v,c ) );
}
/* initial check for is arborescence is possible */
TotV = 0;
TRUE++;
Dfs( Edge,0,false );
if( TotV!=nV ) printf("No arborescene\n",++k );
printf("%ld\n",DMST( Edge ) );
return 0;
}