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

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _bicomponents.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. *  BICONNECTED COMPONENTS                                                      *
  14. *                                                                              *
  15. *  Michael Meiser (1991)                                                       *
  16. *                                                                              *
  17. *******************************************************************************/
  18. #include <LEDA/graph_alg.h>
  19. #include <LEDA/stack.h>
  20. static void bcc_dfs(const graph& G,node v,edge_array<int>& compnum,
  21.                     node_array<int>& dfsnum,node_array<int>& lowpt,
  22.                     node_array<node>& father,stack<node>& current,
  23.                     int& count1,int& count2);
  24. int BICONNECTED_COMPONENTS(const graph& G, edge_array<int>& compnum)
  25. {
  26.   // computes the biconnected components of the underlying  undirected
  27.   // graph,  returns m = number of biconnected components and 
  28.   // in edge_array<int> compnum for each edge an integer with
  29.   // compnum[x] = compnum[y] iff edges x and y belong to the same component 
  30.   // and 0 <= compnum[e] <= m-1 for all edges e
  31.   // running time : O(|V|+|E|)
  32.   //
  33.   // (problem  with self-loops ? )
  34.   stack<node> current;
  35.   node_array<int> dfsnum(G,-1);
  36.   node_array<int> lowpt(G,0);
  37.   node_array<node> father(G,nil);
  38.   int count1 = 0; 
  39.   int count2 = 0;
  40.   node v;
  41.   forall_nodes(v,G)
  42.    if (dfsnum[v] == -1)
  43.     {
  44.      dfsnum[v] = ++count1;
  45.      current.push(v);
  46.      bcc_dfs(G,v,compnum,dfsnum,lowpt,father,current,count1,count2);
  47.     }
  48.   return(count2);
  49.  } // BI_COMPONENTS
  50. static void bcc_dfs(const graph& G,node v,edge_array<int>& compnum,
  51.                     node_array<int>& dfsnum,node_array<int>& lowpt,
  52.                     node_array<node>& father,stack<node>& current,
  53.                     int& count1,int& count2)
  54.  {
  55.   // Precondition: G is undirected
  56.   node w;
  57.   lowpt[v] = dfsnum[v];
  58.   forall_adj_nodes(w,v)
  59.    if (dfsnum[w] == -1)
  60.     {
  61.      dfsnum[w] = ++count1;
  62.      current.push(w);
  63.      father[w] = v;
  64.      bcc_dfs(G,w,compnum,dfsnum,lowpt,father,current,count1,count2);
  65.      lowpt[v] = Min(lowpt[v],lowpt[w]);
  66.     }
  67.    else
  68.     lowpt[v] = Min(lowpt[v],dfsnum[w]);
  69.   if (father[v] && (lowpt[v] == dfsnum[father[v]]))
  70.    // 1.Bedingung nur von Bedeutung fuer Graphen,die nicht zusammen-
  71.    // haengend sind sowie fuer den ersten besuchten Knoten
  72.    {
  73.     edge e;
  74.     do
  75.      {
  76.       w = current.pop();
  77.       forall_adj_edges(e,w)
  78.        if (dfsnum[w] > dfsnum[G.opposite(w,e)])
  79.         compnum[e] = count2;
  80.      }
  81.     while (w != v);
  82.     count2++;
  83.    }
  84.  } // bcc_dfs