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

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _g_misc.c
  6. +
  7. +  Copyright (c) 1995  by  Max-Planck-Institut fuer Informatik
  8. +  Im Stadtwald, 66123 Saarbruecken, Germany     
  9. +  All rights reserved.
  10. *******************************************************************************/
  11. #include <LEDA/graph.h>
  12. #include <LEDA/ugraph.h>
  13. node_array<int>* num_ptr;
  14.   
  15. int epe_source_num(const edge& e) { return (*num_ptr)[source(e)]; }
  16. int epe_target_num(const edge& e) { return (*num_ptr)[target(e)]; }
  17. bool Is_Simple(graph& G)  
  18.   // return true iff G is simple, i.e, has no parallel edges
  19.  
  20.   list<edge>el= G.all_edges();
  21.   node v;
  22.   
  23.   edge e;
  24.   int n= 0;
  25.   
  26.   node_array<int> num(G);
  27.   forall_nodes(v,G) num[v]= n++;
  28.   
  29.   num_ptr= &num;
  30.   
  31.   el.bucket_sort(0,n-1,&epe_source_num);
  32.   el.bucket_sort(0,n-1,&epe_target_num);
  33.   
  34.   int i= -1;
  35.   int j= -1;
  36.   
  37.   forall(e,el)
  38.   { if(j==num[source(e)]&&i==num[target(e)])
  39.     return false;
  40.     else
  41.     { j= num[source(e)];
  42.       i= num[target(e)];
  43.     }
  44.   }
  45.   return true;
  46.   
  47. }
  48.   
  49.   
  50. void Delete_Loops(graph& G)
  51. { list<edge> loops;
  52.   edge e;
  53.   forall_edges(e,G)
  54.     if (source(e) == target(e)) loops.append(e);
  55.   forall(e,loops) G.del_edge(e);
  56.  }
  57. void Make_Simple(graph& G)
  58.   //use bucket sort to find and eliminate parallel edges
  59.   
  60.   list<edge> el = G.all_edges();
  61.   node v;
  62.   edge e;
  63.   int  n = 0;
  64.   node_array<int> num(G);
  65.   forall_nodes(v,G) num[v] = n++;
  66.   
  67.   num_ptr = &num;
  68.   el.bucket_sort(0,n-1,&epe_source_num);
  69.   el.bucket_sort(0,n-1,&epe_target_num);
  70.   
  71.   int i = -1;
  72.   int j = -1; 
  73.   forall(e,el)  
  74.     { if (j==num[source(e)] && i==num[target(e)]) 
  75.         G.del_edge(e);
  76.       else 
  77.         { j=num[source(e)];
  78.           i=num[target(e)];
  79.          }
  80.      }
  81.   
  82.  }
  83. static int edge_ord1(const edge& e) { return index(source(e)); }
  84. static int edge_ord2(const edge& e) { return index(target(e)); }
  85. bool Is_Bidirected(const graph& G, edge_array<edge>& reversal)     
  86. {
  87.  // computes for every edge e = (v,w) in G its reversal reversal[e] = (w,v)
  88.  // in G ( nil if not present). Returns true if every edge has a
  89.  // reversal and false otherwise.
  90.   int n = G.max_node_index();
  91.   int count = 0;
  92.   edge e,r;
  93.   forall_edges(e,G) reversal[e] = 0;
  94.   list<edge> El = G.all_edges();
  95.   El.bucket_sort(0,n,&edge_ord2);
  96.   El.bucket_sort(0,n,&edge_ord1);
  97.   
  98.   list<edge> El1 = G.all_edges();
  99.   El1.bucket_sort(0,n,&edge_ord1);
  100.   El1.bucket_sort(0,n,&edge_ord2);
  101.   // merge El and El1 to find corresponding edges
  102.   while (! El.empty() && ! El1.empty())
  103.   { e = El.head();
  104.     r = El1.head();
  105.     if (target(r) == source(e))
  106.       if (source(r) == target(e))
  107.          { reversal[e] = r;
  108.            El1.pop();
  109.            El.pop();
  110.            count++;
  111.           }
  112.       else
  113.          if (index(source(r)) < index(target(e)))
  114.              El1.pop();
  115.          else
  116.              El.pop();
  117.     else
  118.       if (index(target(r)) < index(source(e)))
  119.           El1.pop();
  120.       else
  121.           El.pop();
  122.     }
  123.   return (count == G.number_of_edges()) ? true : false;
  124. }
  125. #if defined(COMMENT)
  126. static void MB_DFS(graph & G, node v, int &dfs_count, list<edge>& L,
  127.                                       node_array<bool>& reached,
  128.                                       node_array<int>&  dfsnum, 
  129.                                       node_array<int>&  lowpt,
  130.                                       node_array<node>& parent)
  131. {
  132.   node w;
  133.   edge e;
  134.   dfsnum[v] = dfs_count++;
  135.   lowpt[v] = dfsnum[v];
  136.   reached[v] = true;
  137.   if (!G.first_adj_edge(v))
  138.     return; /* no children */
  139.   node u = target(G.first_adj_edge(v)); /* first child */
  140.   forall_adj_edges(e, v) 
  141.   { w = target(e);
  142.     if (!reached[w]) // e is a tree edge
  143.     { parent[w] = v;
  144.       MB_DFS(G, w, dfs_count, L, reached, dfsnum, lowpt, parent);
  145.       if (lowpt[w] == dfsnum[v]) 
  146.       { // |v| is an articulation point. We
  147.         // now add an edge. If |w| is the
  148. // first child and |v| has a parent
  149. // then we connect |w| and
  150. // |parent[v]|, if |w| is a first
  151. // child and |v| has no parent then
  152. // we do nothing. If |w| is not the
  153. // first child then we connect |w| to 
  154. // the first child. The net effect
  155. // of all of this is to link all
  156. // children of an articulation point
  157. // to the first child and the first
  158. // child to the parent (if it
  159. // exists)
  160. if (w == u && parent[v]) 
  161.         { L.append(G.new_edge(w, parent[v]));
  162.   L.append(G.new_edge(parent[v], w));
  163.  }
  164. if (w != u)
  165. { L.append(G.new_edge(u, w));
  166.   L.append(G.new_edge(w, u));
  167.  }
  168.        }
  169.       lowpt[v] = Min(lowpt[v], lowpt[w]);
  170.     } // tree edge
  171.     else
  172.       lowpt[v] = Min(lowpt[v], dfsnum[w]); // non tree edge
  173.   }
  174. }
  175. list<edge> Make_Biconnected(graph & G)
  176. {
  177.   node_array <bool>  reached(G, false);
  178.   list<edge> L;
  179.   node u = G.first_node();
  180.   node v;
  181.   forall_nodes(v, G) 
  182.     if (!reached[v]) // explore the connected component with root v 
  183.     { DFS(G, v, reached);
  184.       if (u != v)   // link v's component to the first component
  185.       { L.append(G.new_edge(u, v));
  186. L.append(G.new_edge(v, u));
  187.        }
  188.      }
  189. // G is now connected. We next make it biconnected.
  190.   reached.init(G,false);
  191.   node_array<int>  dfsnum(G);
  192.   node_array<int>  lowpt(G);
  193.   node_array<node> parent(G,nil);
  194.   int dfs_count = 0;
  195.   MB_DFS(G,G.first_node(), dfs_count, L,reached, dfsnum, lowpt, parent);
  196.   return L;
  197. }
  198. #endif