轉(zhuǎn)貼:
http://baike.baidu.com/view/501092.htm
http://baike.baidu.com/view/501092.htm
匈牙利算法
求最大匹配的一種顯而易見的算法是:先找出全部匹配,然后保留匹配數(shù)最多的。但是這個算法的復雜度為邊數(shù)的指數(shù)級函數(shù)。因此,需要尋求一種更加高效的算法。 增廣路的定義(也稱增廣軌或交錯軌): 若P是圖G中一條連通兩個未匹配頂點的路徑,并且屬M的邊和不屬M的邊(即已匹配和待匹配的邊)在P上交替出現(xiàn),則稱P為相對于M的一條增廣路徑。 由增廣路的定義可以推出下述三個結(jié)論: 1-P的路徑長度必定為奇數(shù),第一條邊和最后一條邊都不屬于M。 2-P經(jīng)過取反操作可以得到一個更大的匹配M’。 3-M為G的最大匹配當且僅當不存在相對于M的增廣路徑。 用增廣路求最大匹配(稱作匈牙利算法,匈牙利數(shù)學家Edmonds于1965年提出) 算法輪廓: (1)置M為空 (2)找出一條增廣路徑P,通過取反操作獲得更大的匹配M’代替M (3)重復(2)操作直到找不出增廣路徑為止 程序清單: #include<stdio.h> #include<string.h> bool g[201][201]; int n,m,ans; bool b[201]; int link[201]; bool init() { ? ? ? ? int _x,_y; ? ? ? ? memset(g,0,sizeof(g)); ? ? ? ? memset(link,0,sizeof(link)); ? ? ? ? ans=0; ? ? ? ? if(scanf("%d%d",&n,&m)==EOF)return false; ? ? ? ? for(int i=1;i<=n;i++) ? ? ? ? { ? ? ? ? ? ? ? ? scanf("%d",&_x); ? ? ? ? ? ? ? ? for(int j=0;j<_x;j++) ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? ? ? scanf("%d",&_y); ? ? ? ? ? ? ? ? ? ? ? ? g[i][_y]=true; ? ? ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? return true; } bool find(int a) { ? ? ? ? for(int i=1;i<=m;i++) ? ? ? ? { ? ? ? ? ? ? ? ? if(g[a][i]==1&&!b[i]) ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? ? ? b[i]=true; ? ? ? ? ? ? ? ? ? ? ? ? if(link[i]==0||find(link[i])) ? ? ? ? ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? link[i]=a; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? return false; } int main() { ? ? ? ? while(init()) ? ? ? ? { ? ? ? ? ? ? ? ? for(int i=1;i<=n;i++) ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? ? ? memset(b,0,sizeof(b)); ? ? ? ? ? ? ? ? ? ? ? ? if(find(i))ans++; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? printf("%d\n",ans); ? ? ? ? } } 下面是同宿舍的小小牛寫的,一起貼上吧,呵呵: #include?<iostream> #include?<fstream>? using?namespace?std;![]() const?int?MAXN?=?100; int?uN,?vN;? bool?g[MAXN][MAXN];//g[i][j]?表示?xi與yj相連? int?xM[MAXN],?yM[MAXN];?//?輸出量? bool?chk[MAXN];?//輔助量?檢查某輪?y[v]是否被check?![]() ![]() ![]() bool?SearchPath(int?u)![]() ![]() { ????int?v; ????for?(v=0;?v<vN;?v++)![]() ???? { ????????if?(g[u][v]?&&?!chk[v])![]() ???????? { ????????????chk[v]?=?true; ????????????if?(yM[v]?==?-1?||?SearchPath(yM[v]))?![]() ???????????? { ????????????????yM[v]?=?u; ????????????????xM[u]?=?v; ????????????????return?true; ????????????} ????????} ????} ????return?false; }![]() int?MaxMatch()![]() ![]() { ????int?u; ????int?ret?=?0; ????memset(xM,?-1,?sizeof(xM)); ????memset(yM,?-1,?sizeof(yM)); ????for?(u=0;?u<uN;?u++)![]() ???? { ????????if?(xM[u]?==?-1)![]() ???????? { ????????????memset(chk,?false,?sizeof(chk)); ????????????if?(SearchPath(u))?ret++; ????????} ????} ????return?ret; }![]() int?main()![]() ![]() { ????int?i,?k;? ????int?tU,?tV; ????ifstream?cin("test.txt"); ????cin?>>?uN?>>?vN?>>?k; ????memset(g,?false,?sizeof(g)); ????for?(i=0;?i<k;?i++)![]() ???? { ????????cin?>>?tU?>>?tV; ????????g[tU][tV]?=?true; ????}? ????cout?<<?MaxMatch()?<<?endl; ????system("pause"); ????return?0;? }?? |






????
????
????????????}
}
{
memset(chk, false, sizeof(chk));
if (SearchPath(u)) ret++;
}
無需判斷xM[u] == -1。