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

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _mcb_matching.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. *  MAX_CARD_BIPARTITE_MATCHING  
  14. *
  15. *  Maximum Cardinality Bipartite Matching
  16. *
  17. *  Implementation of the Hopcroft/Karp algorithm
  18. *
  19. *  J.E. Hopcrof and R.M. Karp 
  20. *  An n^2.5 Algorithm for Maximum Matchings in Bipartite Graphs, 
  21. *  SIAM Journal of Computing, Vol. 2, No. 4, 1973, 225-231
  22. *
  23. *  running time: O(|E|*sqrt(|V|))
  24. *                             
  25. *******************************************************************************/
  26. #include <LEDA/graph_alg.h>
  27. #include <LEDA/b_queue.h>
  28. static int mark;
  29. static edge find_next_augmenting_path(graph& G, node s, node t,
  30.                                       node_array<edge>& pred,
  31.                                       edge_array<int>& layered)
  32. { node w;
  33.   edge e;
  34.   edge f=0;
  35.   while (f==0 && G.next_adj_edge(e,s))
  36.     if (layered[e]==mark)               // e is edge of layered network
  37.       if ((w=target(e))==t) f=e;        // t is reached
  38.       else  if (pred[w]==0)             // w not reached before 
  39.             { pred[w] = e;
  40.               f = find_next_augmenting_path(G,w,t,pred,layered);
  41.              }
  42.   return f;
  43. static bool bfs(graph& G, node s,node t,edge_array<int>& layered)
  44.   node_array<int> dist(G,-1);
  45.   b_queue<node> Q(G.number_of_nodes());
  46.   node v,w;
  47.   edge e;
  48.   Q.append(s);
  49.   dist[s] = 0;
  50.   while (!Q.empty())
  51.   { v = Q.pop();
  52.     if (v==t) return true;
  53.     int dv = dist[v];
  54.     forall_adj_edges(e,v)
  55.     { w = target(e);
  56.       if (dist[w] < 0) 
  57.       { Q.append(w); 
  58.         dist[w] = dv+1;
  59.        }
  60.       if (dist[w] == dv+1) layered[e] = mark;
  61.      }
  62.    }
  63.   return false;
  64. }
  65.   
  66.   
  67. list<edge> MAX_CARD_BIPARTITE_MATCHING(graph& G)
  68. { list<node> A,B;
  69.   node v;
  70.   forall_nodes(v,G)
  71.   if (G.outdeg(v) > 0) 
  72.      A.append(v);
  73.   else 
  74.      if (G.indeg(v) > 0) B.append(v);
  75.   return MAX_CARD_BIPARTITE_MATCHING(G,A,B); 
  76. }
  77. list<edge> MAX_CARD_BIPARTITE_MATCHING(graph& G, const list<node>& A, 
  78.                                                  const list<node>& B )
  79. { // G is a bipartite graph with sides A and B, all edges must be directed 
  80.   // from A to B. We compute a matching of maximum cardinality using the 
  81.   // algorithm of Hopcroft and Karp. The running time is O(sqrt(n)*m).
  82. node v;
  83. edge e;
  84. forall(v,B) 
  85.  { forall_adj_edges(e,v) 
  86.    { G.print_node(v);
  87.      newline;
  88.      G.print_edge(e);
  89.       error_handler(1,"mcb_matching: edge from B to A.");
  90.     }
  91.   }
  92. // heuristic for initial matching
  93. forall_edges(e,G)
  94.   if (G.indeg(source(e))==0 && G.outdeg(target(e)) ==0) G.rev_edge(e);
  95. list<edge> EL;
  96. node s = G.new_node();
  97. node t = G.new_node();
  98. node_array<edge> pred(G,0); 
  99. forall(v,A) if (G.indeg(v)==0) G.new_edge(s,v);
  100. forall(v,B) if (G.outdeg(v)==0) G.new_edge(v,t);
  101. edge_array<int> layered(G,0);
  102. mark = 1;
  103. G.reset();
  104. for(;;)
  105. { forall_nodes(v,G) pred[v] = 0;
  106.   mark++;
  107.   if (bfs(G,s,t,layered))  
  108.   {
  109.     // there is at least one augmenting path
  110.     while (e = find_next_augmenting_path(G,s,t,pred,layered)) EL.append(e); 
  111.     G.reset();
  112.     while (!EL.empty())
  113.     { edge e=EL.pop();
  114.       edge x = pred[source(e)];
  115.       while (source(x) != s)
  116.       { G.rev_edge(x);
  117.         x=pred[target(x)];
  118.        }
  119.       G.del_edge(e);  // edge into t
  120.       G.del_edge(x);  // edge out of s
  121.      } 
  122.    }
  123.   else break;
  124. list<edge> result;
  125. forall(v,B) 
  126. { forall_adj_edges(e,v) 
  127.      if (target(e) != t) 
  128.         result.append(e);
  129.      else
  130.         EL.append(e);
  131.  }
  132. //restore graph:
  133. forall(e,EL) G.del_edge(e);
  134. forall(e,result) G.rev_edge(e);
  135. G.del_node(s);
  136. G.del_node(t);
  137. return result;
  138. }