home *** CD-ROM | disk | FTP | other *** search
- /*******************************************************************************
- +
- + LEDA 2.1.1 11-15-1991
- +
- +
- + _transclosure.c
- +
- +
- + Copyright (c) 1991 by Max-Planck-Institut fuer Informatik
- + Im Stadtwald, 6600 Saarbruecken, FRG
- + All rights reserved.
- +
- *******************************************************************************/
-
-
-
- /*******************************************************************************
- * *
- * TRANSITIVE_CLOSURE (transitive closure) *
- * *
- *******************************************************************************/
-
-
-
- #include <LEDA/graph_alg.h>
-
- /*
- #include <LEDA/array.h>
-
- declare(array,node)
- */
-
- typedef list(node)* nodelist_ptr;
-
- declare2(GRAPH,nodelist_ptr,int)
-
-
- graph TRANSITIVE_CLOSURE(const graph& G0)
- {
- node v,w;
- edge e;
- int i,j;
-
- graph G = G0;
-
- node_array(int) compnum(G);
- int k = STRONG_COMPONENTS(G,compnum);
-
- /* reduce graph G to graph G1 = (V',E')
- with V' = { V[0],V[1],...,V[k] } = set of scc's of G
- and (V[i],V[j]) in E' iff there is an edge from V[i] to V[j] in G
-
- G1.inf(V[i]) = set of nodes v in G with v in scc i (i.e. compum[v] = i)
- */
-
- GRAPH(nodelist_ptr,int) G1;
-
- // array(node) V(k);
-
- node* V = new node[k];
-
- loop(j,0,k-1) V[j] = G1.new_node(new list(node));
-
- forall_nodes(v,G) G1.inf(V[compnum[v]])->append(v);
-
- forall_edges(e,G)
- { i = compnum[source(e)];
- j = compnum[target(e)];
- if (i!=j) G1.new_edge(V[i],V[j]);
- }
-
- eliminate_parallel_edges(G1);
-
- // compute transitive closure of acyclic graph G1
-
- acyclic_transitive_closure(G1);
-
- edgelist el = G.all_edges();
- forall(e,el) G.del_edge(e);
-
- node x,y;
-
- forall_nodes(v,G1)
- { list(node) nl1 = *(G1[v]);
- forall_adj_nodes(w,v)
- { forall(x,nl1)
- forall(y,*(G1[w])) G.new_edge(x,y);
- }
- }
-
- forall_nodes(v,G1) G1[v]->clear();
-
- delete V;
-
- return G;
- }
-
-