二分图最大匹配问题
1、網絡流
給定一個二分圖G = (X, E, Y)。構造與G對應的網絡G‘, 構造方法如下:
(1)增加一個源點s, 一個匯點t 。
(2)從s向X的每個頂點引一條有向邊,從Y的每個頂點向t引一條有向邊。
(3)將原圖G的每一條邊改為從X指向Y的有向邊。
(4)讓所有的邊容量為1 。
然后求最大流,就是二分圖的最大匹配邊數。
2、匈牙利算法
??? 首先定義增廣路:若P是圖G種一條聯通兩個未匹配定點的路徑,并且屬于M的邊和不屬于M的邊(已匹配的邊和未匹配的邊)在P上交替出現,則稱P為相對于M的一條增廣路。特別地,當一邊(v, v')兩端點均為非M-頂點,通路(v, v')亦稱為增廣路。
算法具體實現:
???(1)首先用(*)標記X中所有的非M-頂點,然后交替進行步驟(2),(3)。
????(2)選取一個剛標記(用(*)或在步驟(3)中用(yi)標記)過的X中頂點,例如頂點xi,然后用(xi)去標記Y中頂點y,如果xi與y為同一非匹配邊的兩端點,且在本步驟中y尚未被標記過。重復步驟(2),直至對剛標記過的X中頂點全部完成一遍上述過程。
????(3)選取一個剛標記(在步驟(2)中用(xi)標記)過的Y中結點,例如yi,用(yi)去標記X中結點x,如果yi與x為同一匹配邊的兩端點,且在本步驟中x尚未被標記過。重復步驟(3),直至對剛標記過的Y中結點全部完成一遍上述過程。
(2),(3)交替執行,直到下述情況之一出現為止:
????(Ⅰ)標記到一個Y中頂點y,它不是M-頂點。這時從y出發循標記回溯,直到(*)標記的X中頂點x,我們求得一條增廣路。設其長度為2k+1,顯然其中k條是匹配邊,k+1條是非匹配邊。
????(Ⅱ)步驟(2)或(3)找不到可標記結點,而又不是情況(Ⅰ)。
????(4)?當?(2),(3)步驟中斷于情況(Ⅰ),則將增廣路中非匹配邊改為匹配邊,原匹配邊改為非匹配邊(從而得到一個比原匹配多一條邊的新匹配),回到步驟(1),同時消除一切現有標記。
????(5)對一切可能,(2)和(3)步驟均中斷于情況(Ⅱ),或步驟(1)無可標記結點,算法終止(算法找不到增廣路)。
轉自:http://hi.baidu.com/sysucs/blog/item/c1c58dee4c5247282df53484.html
?
2-21:
今天做一下補充,在Matrix67 大神的解釋:
說穿了,就是你從二分圖中找出一條路徑來,讓路徑的起點和終點都是還沒有匹配過的點,并且路徑經過的連線是一條沒被匹配、一條已經匹配過,再下一條又沒匹配這樣交替地出現。找到這樣的路徑后,顯然路徑里沒被匹配的連線比已經匹配了的連線多一條,于是修改匹配圖,把路徑里所有匹配過的連線去掉匹配關系,把沒有匹配的連線變成匹配的,這樣匹配數就比原來多1個。不斷執行上述操作,直到找不到這樣的路徑為止。
?
?? 下面是匈牙利算法的實現:
?
1 bool dfs(int t) {2 for(int i = 1; i <= stu; i++) {
3 if(!usd[i] && g[t][i]) {
4 usd[i] = true;
5 if(Link[i] == -1 || dfs(Link[i])) {
6 Link[i] = t;
7 return true;
8 }
9 }
10 }
11 return false;
12 }
13
14 for(i = 1; i <= cou; i++) {
15 memset(usd, 0, sizeof(usd));
16 if(dfs(i)) ans++;
17 }
?
?
?
??????????? ????????? ?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
總結
- 上一篇: IE6 CSS的一个bug
- 下一篇: oracle数据字典表与视图