匈牙利算法是由匈牙利數學家Edmonds於1965年提出,於是得名。匈牙利算法是基於Hall定理中充分性證實的思想,它是部圖匹配最多見的算法,該算法的核心就是尋找增廣路徑,它是一種用增廣路徑求二分圖最大匹配的算法。算法
既然是解決二分圖的最大匹配問題的算法,那麼,就先來了解一下二分圖是什麼(來自度娘):學習
二分圖又稱做二部圖,是圖論中的一種特殊模型。 設G=(V,E)是一個無向圖,若是頂點V可分割爲兩個互不相交的子集(A,B),而且圖中的每條邊(i,j)所關聯的兩個頂點i和j分別屬於這兩個不一樣的頂點集(i in A,j in B),則稱圖G爲一個二分圖。spa
舉個例子:下面就是一個二分圖,咱們能夠發現,這個圖上的頂點都被塗上了藍(好像有點像紫色)或綠兩種顏色,而且沒有同色的相鄰頂點,這種判斷二分圖的方法叫作染色法.net
既然瞭解了二分圖,那咱們就能夠開始學習匈牙利算法了。code
可是,教科書上的專業語言真的讓人很頭大,要是看教科書,我可能這輩子都學不會匈牙利算法,可是我發現了一個頗有趣的方法對象
假設你是一位光榮的新世紀媒人,在你的手上有N個剩男,M個剩女,每一個人均可能對多名異性有好感,若是一對男女互有好感,那麼你就能夠把這一對撮合在一塊兒,如今讓咱們無視掉全部的單相思,你擁有的大概就是下面這樣一張關係圖,每一條連線都表示互有好感。blog
如今,你須要儘可能多的撮合CP,用匈牙利算法,就是這樣的:get
1、先給1號男嘉賓找對象,你最早找到的即是1號女嘉賓,因此就先把他們連在一塊兒數學
2、 接着,你要給2號男嘉賓找對象,就找到了2號女嘉賓,就把他們也連到一塊兒io
3、接着,到了3號男嘉賓,但是1號女嘉賓已經名花有主了,那咱們就嘗試給1號男嘉賓另分配一個女嘉賓
與1號男嘉賓相連的第二個女生是2號女嘉賓,可是2號女嘉賓也有主了,咱們再試着給2號男嘉賓從新找個妹子(同上)
3、這個時候咱們發現,2號男嘉賓還能夠找3號女嘉賓,這樣問題就解決了,咱們就只須要:
2號男嘉賓能夠找3號女嘉賓 1號男嘉賓能夠找2號女嘉賓 3號男嘉賓能夠找1號女嘉賓
因此目前的結果就是這樣:
4、接下來是4號男嘉賓,很遺憾,按照第三步的方法咱們無法給4號男嘉賓騰出來一個女嘉賓
因此匈牙利算法的基本原則即是:有機會就上,沒機會創造機會也要上
模板以下:
1 bool dfs(int x){ 2 int i, j; 3 for (j=1; j<=m; j++){ //掃描每一個妹子 4 if (line[x][j] && !used[j]){ //若是有好感而且尚未標記過 5 used[j]=1; 6 if (girl[j] == 0 || dfs(girl[j])) { //名花無主或者能騰出個位置來 7 girl[j]=x; 8 return true; 9 } 10 } 11 } 12 return false; 13 }
而主程序咱們就只須要循環一下就行了:
1 for (i=1;i<=n;i++) 2 { 3 memset(used,0,sizeof(used)); //在每一步中清空 4 if (dfs(i)) ans+=1; 5 }