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

  1. /*******************************************************************************
  2. +
  3. +  LEDA  2.1.1                                                 11-15-1991
  4. +
  5. +
  6. +  _trans_acyclic.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. #include <LEDA/graph_alg.h>
  17.  
  18.  
  19. typedef list(node)* nodelist_ptr;
  20.  
  21. declare(node_array,list_item)
  22.  
  23. /*
  24. #include <LEDA/array.h>
  25.  
  26. declare(array,nodelist_ptr)
  27. declare(array,node)
  28. declare(array2,int)
  29. */
  30.  
  31.  
  32. void acyclic_transitive_closure(graph& G)
  33. { // computes transitive closure of acyclic graph G
  34.  
  35. edgelist E1;
  36. node v,w;
  37.  
  38. int i,j,k,h;
  39. int n = G.number_of_nodes();
  40.  
  41. TOPSORT1(G); 
  42.  
  43. node_array(bool)      marked(G);
  44. node_array(int)       top_ord(G);      // topologic order
  45.  
  46. // array(nodelist_ptr)   C(n+1);          // chains C[1], C[2], ...
  47.  
  48. nodelist_ptr*   C = new nodelist_ptr[n+1];
  49.  
  50. node_array(int)       chain(G);        // chain[v] = i  iff  v in C[i]
  51. node_array(list_item) chain_loc(G);    // chain_loc[v]   
  52.                                        //  = location of v in its chain
  53.  
  54. /*
  55. array(node)      N(n);            // N[i]     = node i (in topological order)
  56. array2(int)      reach(n,n);      // reach[h][i] = min { j ; N[j] in C[h] and
  57.                                   // there is a path from N[i] to N[j] }
  58. */
  59.  
  60. node* N     = new node[n];
  61.  
  62. int** reach = new int*[n];
  63. for(i=0; i<n; i++) reach[i] = new int[n];
  64.  
  65.                      
  66. i=0;
  67. forall_nodes(v,G) { marked[v]=1; top_ord[v] = i; N[i]=v; i++; }
  68.  
  69. //Kettenzerlegung C[0], C[1], ..., C[k]
  70.  
  71. k=0;
  72. C[0] = new list(node);
  73. forall_nodes(v,G) 
  74.  { node v0 = v;
  75.    if (marked[v0])
  76.     {  chain_loc[v0]=C[k]->append(v0);  
  77.        chain[v0]=k;
  78.        while (v0)
  79.        { forall_adj_nodes(w,v0) if (marked[w]) break; 
  80.          if (w) { marked[w]=0;
  81.                   chain[w]=k;
  82.                   chain_loc[w]=C[k]->append(w);
  83.                  }
  84.          v0=w;
  85.        }
  86.        k++;
  87.        C[k] = new list(node);
  88.     }
  89.   }
  90. k--;
  91.  
  92.  
  93. for(h=0; h<n; h++)
  94.   for(i=0; i<n; i++)
  95.     reach[h][i] = n+1;
  96.  
  97. Forall_nodes(v,G)       //decreasing order
  98. { i=top_ord[v];
  99.   forall_adj_nodes(w,v) //increasing order
  100.   { j=top_ord[w];
  101.     if (j <= reach[chain[w]][j])
  102.      for(h=0; h<=k; h++)
  103.        if (reach[h][j] < reach[h][i]) reach[h][i] = reach[h][j];
  104.   }
  105.   reach[chain[v]][i] = i;
  106. }
  107.  
  108.  
  109. G.del_all_edges();
  110.  
  111. forall_nodes(v,G)
  112. { for(i=0; i<=k; i++)
  113.     if ((j=reach[i][top_ord[v]]) < n+1)
  114.     { C[i]->set_iterator(C[i]->pred(chain_loc[N[j]]));
  115.       while (C[i]->next_element(w)) G.new_edge(v,w);
  116.      }
  117.  }
  118.  
  119. for(i=0; i<=k; i++) C[i]->clear();
  120.  
  121. for(i=0; i<n; i++) delete reach[i];
  122.  
  123. delete reach;
  124. delete C;
  125. delete N;
  126.  
  127. }
  128.  
  129.  
  130.