匈牙利算法
阿新 • • 發佈:2017-07-15
來看 png oid 分享 輸出 scanf nbsp 二分圖最大匹配 spa
匈牙利算法其實就是一種遞歸,是由匈牙利數學家提出,該算法的核心就是尋找增廣路經,它是一種用增廣路徑求二分圖最大匹配的算法。
其時間復雜度為O(v*e),v為左邊的個數,e為右邊的個數。
這是一個二分圖,現在求這個圖的最大匹配。
(1)
最開始的匹配會得到
1->A; 2->B;
(2)
當對3進行匹配時,會發現3所對應的A和B 都已經被匹配完畢。此時為了大局著想,1和2必須為3讓位。
首先1把A讓給3,即 3->A;
此時會發現1還有可以用來對應的,於是2把B讓位給1,即1->B;
然後2呢也會有一個與其對應的字母C,所以3->C;
(3)
此時再來看4這個數字,由於他只能跟C進行匹配,所以假設4->C;
那麽1,2,3就沒有足夠的字母來與其對應,所以4並沒有能找到預期匹配的項。
所以這個二分匹配圖的最大匹配就為3
算法實現:
1 //首先要進行初始化,將可以進行匹配的記錄下來 2 void init() 3 { 4 for(int i=0;i<n;i++) 5 { 6 scanf("%d %d",&a,&b); 7 g[a][b]=1;//a和b是可以進行匹配的 8 } 9 }
然後就是對每個的數字進行遍歷,尋找最大匹配的數量
1 for(int i=1;i<=4;i++) 2 { 3 memset(mark,0,sizeof(mark)); 4 //將字母進行初始化,也就是所有的字母沒有被選過 5 if(find(i)) 6 { 7 ans++; 8 } 9 } 10 //輸出結果
其中該算法的核心就是進行多次匹配的時候的“讓”了。
1 int find(int x) 2 { 3 for(int i=1;i<=4;i++) 4 { 5 if(g[x][i]==1&&mark[i]==0) 6 { 7 mark[i]=1; 8 //如果字母沒有被匹配,而且可以通過更改之前匹配的項 9 //讓其可以得到一個對應的字母,那麽就返回1 10 if(zm[i]==0||find(zm[i])) 11 { 12 zm[i]=x; 13 return 1; 14 } 15 } 16 } 17 return 0; 18 }
匈牙利算法