--- title: 二分圖最大匹配與匈牙利演算法 tags: 7th 教學 slideOptions: theme: black transition: 'slide' --- # 二分圖最大匹配與匈牙利演算法 #### Author:H1de_on_bruH ## 何謂二分圖? 試想一個情境 學校裡有很多男生跟女生,他們各自有一些喜歡的對象 而到了歲末舞會,這些男女們就會開始湊成一對一對的 當然這些人中不乏一些渣男渣女,表面上跟你很好,實際上有很多對象 但你是校長,你才不管有哪些人沒有伴,你只在乎最多可以湊出多少對  那調查完所有人喜歡的對象後,我們可以畫出像上方的一張圖,學術上稱之為二分圖 所謂二分圖就是你可以把這個圖的節點分成兩個集合,同個集合內的點不直接相連 現在你關心的最多有幾對,就可以被轉化成二分圖最大匹配 ## 匈牙利演算法 我們從A開始看,他和a,b都有一些"良好"的關係 所以我們暫時把A跟a湊成一對  接下來看到B,他只跟c有曖昧,所以我們就把他們湊一對  最後我們看到C,他只跟a有關係,但此時A跟a已經湊一對了 那一般我們會試著打斷配對,重新配配看,也就是說把C跟a配一對後,讓A再去找一次  於是我們回到A,A跟a,b有關係,因為剛剛就已經知道為甚麼A不能跟a配了,現在連智障都可以很清楚的告訴你,我們現在只能讓A跟b配對 只不過我們要怎麼樣寫出程式讓電腦合理推測我們A接下來要跟誰配呢? 那我們就是測試看看A跟a配之後,C能不能再配 如果可以C就放掉 那不行的話A就只能再考慮其他的對象,於是輪到b 發現b沒有配到對像,所以就直接配下去  $於是乎,我們就找到最多的配對數了_{めでたしめでたし}$ ## 最小點覆蓋 最小點覆蓋數的意思就是,我們最少要選多少個點,才可以把所有的邊的其中一點都給覆蓋住? 如果你想跳過嚴謹的證明,那我們可以直接看結論,也就是 >最小點覆蓋數=最大匹配數 > ----König定理 那詳細的證明請參見下方連結 ~~因為筆者本人也只有背結論不知道怎麼證明~~ www.matrix67.com/blog/archives/116 ## 例題 ### [TIOJ#1253](https://tioj.ck.tp.edu.tw/problems/1253) 經典的匈牙利演算法裸題 我們先這樣建模: >假設(i,j)上有隻皮皮,那我們就在圖上讓i點連到j點 >這樣可以弄出一個二分圖,我們要求用的最少次數就會是這2N個點的最小點覆蓋 可以利用König定理把最小點覆蓋數轉換成最大匹配數 這樣我們就可以輕鬆的AC這題 甚麼?你不會實作匈牙利?那就點下面的箱子學學這個神奇的東西吧 :::spoiler 點我看實作 ```cpp= //TIOJ#1253 #include<bits/stdc++.h> using namespace std; const int N=2e3+5; int n,m,path[N][N],p[N],vis[N]; bool match(int now) { for(int i=n;i<=2*n;i++) { if(path[now][i]&&vis[i]==0) { vis[i]=1; if(p[i]==0||match(p[i])) { p[i]=now; return true; } } } return false; } int hungarian() { int ans=0; for(int i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); if(match(i))ans++; } return ans; } int counter; void solve() { for(int i=1;i<=n;i++)for(int j=n+1;i<=2*n;i++)path[i][j]=p[i]=p[j]=0; for(int i=0;i<m;i++) { int a,b;cin>>a>>b; path[a][b+n]=1; path[b+n][a]=1; } cout<<"Case #"<<++counter<<":"; cout<<hungarian()<<endl; } signed main() { while(cin>>n>>m&&n&&m)solve(); } ``` ::: --- ### [洛谷P2756](https://www.luogu.com.cn/problem/P2756) 比上面更裸的題目,這次是要求出最大的配對方法,那只要把i跟p[i]成對輸出就可以解了 :::spoiler 點我看解 https://www.luogu.com.cn/record/63994967 ::: ## Outline:[網路流建模](https://www.youtube.com/watch?v=u4dw3KuTz5s&t=108s) :::spoiler 本篇的夕張  哈密哈>\\\\\\\< :::
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up