1. 程式人生 > >匈牙利算法

匈牙利算法

來看 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 }

匈牙利算法