Advertisement
LinKin

Chu-Li-Edmonds

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