_strongcomp.c
上传用户:gzelex
上传日期:2007-01-07
资源大小:707k
文件大小:3k
开发平台:

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _strongcomp.c
  6. +
  7. +  Copyright (c) 1995  by  Max-Planck-Institut fuer Informatik
  8. +  Im Stadtwald, 66123 Saarbruecken, Germany     
  9. +  All rights reserved.
  10. *******************************************************************************/
  11. /*******************************************************************************
  12. *                                                                              *
  13. *  STRONG_COMPONENTS (strong connected components)                             *
  14. *                                                                              *
  15. *******************************************************************************/
  16. #include <LEDA/graph_alg.h>
  17. static void scc_dfs(const graph& G, node v, node_array<int>& compnum,
  18.                                             node_array<int>& dfsnum,
  19.                                             node_list& unfinished,
  20.                                             list<node>& roots,
  21.                                             int& count1, int& count2 );
  22. int STRONG_COMPONENTS(const graph& G, node_array<int>& compnum)
  23. {
  24.   // int STRONG_COMPONENTS(graph& G, node_array<int>& compnum)
  25.   // computes strong connected components (scc) of digraph G
  26.   // returns m = number of scc 
  27.   // returns in node_array<int> compnum for each node an integer with
  28.   // compnum[v] = compnum[w] iff v and w belong to the same scc
  29.   // 0 <= compnum[v] <= m-1 for all nodes v
  30.   list<node>     roots;
  31.   node_list      unfinished;
  32.   node_array<int> dfsnum(G,-1);
  33.   int count1 = 0; 
  34.   int count2 = 0;
  35.   node v;
  36.   forall_nodes(v,G) 
  37.       if (dfsnum[v] == -1) 
  38.        scc_dfs(G,v,compnum,dfsnum,unfinished,roots,count1,count2);
  39.   return count2;
  40. }
  41. static void scc_dfs(const graph& G, node v, node_array<int>& compnum,
  42.                                             node_array<int>& dfsnum,
  43.                                             node_list& unfinished,
  44.                                             list<node>& roots,
  45.                                             int& count1, int& count2 )
  46. {
  47.   node w;
  48.   dfsnum[v] = ++count1;
  49.   unfinished.push(v);
  50.   roots.push(v);
  51.   forall_adj_nodes(w,v)
  52.     { if (dfsnum[w]==-1) 
  53.        scc_dfs(G,w,compnum,dfsnum,unfinished,roots,count1,count2);
  54.       else 
  55.        if (unfinished(w))
  56.         while (dfsnum[roots.head()]>dfsnum[w])  roots.pop();
  57.      }
  58.   if (v==roots.head()) 
  59.    { do { w=unfinished.pop();
  60.           /* w is an element of the scc with root v */
  61.           compnum[w] = count2;
  62.          } while (v!=w);
  63.      count2++;
  64.      roots.pop(); 
  65.     }
  66. }
  67. int STRONG_COMPONENTS1(graph& G, node_array<int>& compnum)
  68.   node v,w;
  69.   int n = G.number_of_nodes();
  70.   int count = 0;
  71.   node* V = new node[n+1];
  72.   list<node> S;
  73.   node_array<int> dfs_num(G);
  74.   node_array<int> compl_num(G);
  75.   node_array<bool> reached(G,false);
  76.   DFS_NUM(G,dfs_num,compl_num);
  77.   forall_nodes(v,G) V[compl_num[v]] = v;
  78.   G.rev();
  79.   for(int i=n; i>0; i--)
  80.    { if ( !reached[V[i]] ) 
  81.       { S = DFS(G,V[i],reached);
  82.         forall(w,S) compnum[w] = count;
  83.         count++;
  84.        }
  85.     }
  86.  delete V;
  87.  return count;
  88.    
  89.  }