home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / diverses / leda / src / graph_al / _transcl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-15  |  2.1 KB  |  98 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  2.1.1                                                 11-15-1991
  4. +
  5. +
  6. +  _transclosure.c
  7. +
  8. +
  9. +  Copyright (c) 1991  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15.  
  16. /*******************************************************************************
  17. *                                                                              *
  18. *  TRANSITIVE_CLOSURE (transitive closure)                                     *
  19. *                                                                              *
  20. *******************************************************************************/
  21.  
  22.  
  23.  
  24. #include <LEDA/graph_alg.h>
  25.  
  26. /*
  27. #include <LEDA/array.h>
  28.  
  29. declare(array,node)
  30. */
  31.  
  32. typedef list(node)* nodelist_ptr;
  33.  
  34. declare2(GRAPH,nodelist_ptr,int)
  35.  
  36.  
  37. graph TRANSITIVE_CLOSURE(const graph& G0)
  38. {
  39.   node v,w;
  40.   edge e;
  41.   int i,j;
  42.  
  43.   graph G = G0;
  44.  
  45.   node_array(int) compnum(G);
  46.   int k = STRONG_COMPONENTS(G,compnum);
  47.  
  48. /* reduce graph G to graph G1 = (V',E') 
  49.    with V' = { V[0],V[1],...,V[k] } = set of scc's of G
  50.    and (V[i],V[j]) in E' iff there is an edge from V[i] to V[j] in G
  51.  
  52.    G1.inf(V[i]) = set of nodes v in G with v in scc i (i.e. compum[v] = i)
  53. */
  54.  
  55.   GRAPH(nodelist_ptr,int) G1;
  56.  
  57.   // array(node) V(k);
  58.  
  59.   node*  V = new node[k];
  60.  
  61.   loop(j,0,k-1) V[j] = G1.new_node(new list(node));
  62.  
  63.   forall_nodes(v,G) G1.inf(V[compnum[v]])->append(v);
  64.   
  65.   forall_edges(e,G)
  66.   { i = compnum[source(e)];
  67.     j = compnum[target(e)];
  68.     if (i!=j) G1.new_edge(V[i],V[j]);
  69.    }
  70.  
  71.   eliminate_parallel_edges(G1);
  72.   
  73.   // compute transitive closure of acyclic graph G1
  74.  
  75.   acyclic_transitive_closure(G1);
  76.  
  77.   edgelist el = G.all_edges();
  78.   forall(e,el) G.del_edge(e);
  79.   
  80.   node x,y;
  81.  
  82.   forall_nodes(v,G1)
  83.   { list(node) nl1 = *(G1[v]);
  84.     forall_adj_nodes(w,v)
  85.      { forall(x,nl1)
  86.          forall(y,*(G1[w])) G.new_edge(x,y);
  87.       }
  88.    }
  89.   
  90.    forall_nodes(v,G1) G1[v]->clear();
  91.   
  92.    delete V;
  93.  
  94.    return G;
  95. }
  96.  
  97.