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

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _transclosure.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. *  TRANSITIVE_CLOSURE (transitive closure)                                     *
  14. *                                                                              *
  15. *******************************************************************************/
  16. #include <LEDA/graph_alg.h>
  17. typedef list<node>* nodelist_ptr;
  18. static void acyclic_transitive_closure(graph& G)
  19. { // computes transitive closure of acyclic graph G
  20. node v,w;
  21. int i,j,k,h;
  22. int n = G.number_of_nodes();
  23. TOPSORT1(G); 
  24. node_array<int> marked(G);
  25. node_array<int> top_ord(G);   // topologic order
  26. node_array<int> chain(G);     // chain[v] = i  iff  v in C[i]
  27. node_list* C = new node_list[n+1];  // chains C[0], C[1], ...
  28. node*      N = new node[n];         // N[i] = i-th node in topological order
  29. int**      reach = new int*[n];     // reach[h][i] = min { j ; N[j] in C[h] and
  30.                                     // there is a path from N[i] to N[j] }
  31. for(i=0; i<n; i++) reach[i] = new int[n];
  32. i=0;
  33. forall_nodes(v,G) { marked[v]=1; top_ord[v] = i; N[i]=v; i++; }
  34. // compute chain decomposition C[0], C[1], ..., C[k]
  35. k=0;
  36. forall_nodes(v,G) 
  37.  { node v0 = v;
  38.    if (marked[v0])
  39.     {  C[k].append(v0);  
  40.        chain[v0]=k;
  41.        while (v0 != nil)
  42.        { node u = nil;
  43.          forall_adj_nodes(w,v0) 
  44.            if (marked[w]) 
  45.            {  u = w;
  46.               break; 
  47.             }
  48.          if (u != nil) 
  49.          { marked[u]=0;
  50.            chain[u]=k;
  51.            C[k].append(u);
  52.           }
  53.          v0=u;
  54.         }
  55.        k++;
  56.     }
  57.   }
  58. k--;
  59. for(h=0; h<n; h++)
  60.   for(i=0; i<n; i++)
  61.     reach[h][i] = n+1;
  62. Forall_nodes(v,G)       //decreasing order
  63. { i=top_ord[v];
  64.   forall_adj_nodes(w,v) //increasing order
  65.   { j=top_ord[w];
  66.     if (j <= reach[chain[w]][j])
  67.      for(h=0; h<=k; h++)
  68.        if (reach[h][j] < reach[h][i]) reach[h][i] = reach[h][j];
  69.   }
  70.   reach[chain[v]][i] = i;
  71. }
  72. G.del_all_edges();
  73. forall_nodes(v,G)
  74.   for(i=0; i<=k; i++)
  75.     { j = reach[i][top_ord[v]];
  76.       if ( j < n+1 )
  77.         for(w = N[j]; w != nil; w = C[i].succ(w)) G.new_edge(v,w);
  78.      }
  79. for(i=0; i<=k; i++) C[i].clear();
  80. delete[] C;
  81. for(i=0; i<n; i++) delete reach[i];
  82. delete reach;
  83. delete N;
  84. }
  85. graph TRANSITIVE_CLOSURE(const graph& G0)
  86. {
  87.   node v,w;
  88.   edge e;
  89.   int i,j;
  90.   graph G = G0;
  91.   node_array<int> compnum(G);
  92.   int k = STRONG_COMPONENTS(G,compnum);
  93. /* reduce graph G to graph G1 = (V',E') 
  94.    with V' = { V[0],V[1],...,V[k] } = set of scc's of G
  95.    and (V[i],V[j]) in E' iff there is an edge from V[i] to V[j] in G
  96.    G1.inf(V[i]) = set of nodes v in G with v in scc i (i.e. compum[v] = i)
  97. */
  98.   GRAPH<nodelist_ptr,int> G1;
  99.   node*  V = new node[k];
  100.   for(j=0; j < k; j++) V[j] = G1.new_node(new list<node>);
  101.   forall_nodes(v,G) 
  102.   { int i = compnum[v];
  103.     G1[V[i]]->append(v);
  104.    }
  105.   
  106.   forall_edges(e,G)
  107.   { i = compnum[source(e)];
  108.     j = compnum[target(e)];
  109.     if (i!=j) G1.new_edge(V[i],V[j]);
  110.    }
  111.   Make_Simple(G1);  // eliminate parallel edges
  112.   
  113.   // compute transitive closure of acyclic graph G1
  114.   acyclic_transitive_closure(G1);
  115.   G.del_all_edges();
  116.   forall_nodes(v,G1)
  117.   { list<node>* plv = G1[v];
  118.     forall_adj_nodes(w,v)
  119.     { list<node>* plw = G1[w];
  120.       list_item x,y;
  121.       forall_items(x,*plv)
  122.          forall_items(y,*plw) 
  123.             G.new_edge(plv->inf(x),plw->inf(y));
  124.      }
  125.    }
  126.    forall_nodes(v,G1) delete G1[v];
  127.   
  128.    delete V;
  129.    return G;
  130. }