18 December 2014

理论基础

Berge 定理:图 G 的匹配 M 是最大匹配的充要条件是 G 中不存在 M 可扩展路。

Hall 定理:设 G 是具有二划分 (X, Y) 的二部图,则 G 有饱和 X 的匹配当且仅当对 $\forall S \subseteq X, |N(S)|\ge |S|$,其中 N(S) 表示 S 的所有邻点之集。

算法步骤

输入:二部图 G=(X, Y).

输出:G 的一个最大匹配 M .

第0步:任取图 G 的一个匹配 M 设 X 中 M 非饱和点的集合为 A.

第1步:若$A=\phi$,则停止,输出当前的 M;否则,任取$x\in A$,记 S := {x},T := $\phi$,转到下一步.

第2步:若$N(S)\subseteq T$,则不存在从 x 出发的 M 增广路,令 A := A - {x},转第一步;否则,取$y\in N(S)-T$ 转下步.

第3步:若y是 M 饱和的,设 $yz\in M$,令 $S := S\bigcup {z}$,$T := T\bigcup {y}$,转第1步;否则获得一条 M 增广路 P(x, y),令 M := M$\oplus$E(P), A := A - {x, y},转第一步.

参考代码

 1 const int MAXN = 1000;
 2 int uN, vN; // u, v数目,要初始化!!!
 3 bool g[MAXN][MAXN]; // g[i][j] 表示xi与yj相连
 4 int xM[MAXN], yM[MAXN]; // 输出量
 5 bool chk[MAXN]; // 辅助量检查某轮y[v]是否被check
 6 bool SearchPath(int u){
 7     int v;
 8     for(v = 0; v < vN; v++)
 9         if(g[u][v] && !chk[v])
10         {
11             chk[v] = true;
12             if(yM[v] == -1 || SearchPath(yM[v]))
13             {
14                 yM[v] = u; xM[u] = v;
15                 return true ;
16             }
17         }
18     return false ;
19 }
20 int hungary(){
21     int u, ret = 0 ;
22     memset(xM, -1, sizeof (xM));
23     memset(yM, -1, sizeof (yM));
24     for(u = 0; u < uN; u++)
25         if(xM[u] == -1){
26             memset(chk, false, sizeof (chk));
27             if(SearchPath(u)) ret++;
28         }
29     return ret;
30 }


blog comments powered by Disqus