匈牙利演算法2018-10-14
阿新 • • 發佈:2018-11-09
看到這一題
或者這個
優秀Blog
其實,這一道題起源於俄羅斯網站上的一道舞會題·······
不管這麼多,先看一看題目:
【模板】二分圖匹配
題目背景
二分圖
感謝@一扶蘇一 提供的hack資料題目描述
給定一個二分圖,結點個數分別為n,m,邊數為e,求二分圖最大匹配數
輸入輸出格式
輸入格式:
第一行,n,m,e
第二至e+1行,每行兩個正整數u,v,表示u,v有一條連邊輸出格式:
共一行,二分圖最大匹配
輸入輸出樣例
輸入樣例#1:
1 1 1
1 1輸出樣例#1:
1
說明n,m≤1000, 1≤u≤n,1≤v≤m
因為資料有坑,可能會遇到 v>m 的情況。請把 v>m 的資料自覺過濾掉。演算法:二分圖匹配
思路:這裡就可以考慮匈牙利演算法了,首先,先掃描所有的男生,如果男生有可以匹配的女生,就可以連上,之後,如果有另一個男生也可以連這個女生,就讓那個男生看一看能不能換一個人(橫刀奪愛)
程式碼:
#include <bits/stdc++.h>
using namespace std;
const int maxn=1000+10;
bool d[maxn][maxn],b[maxn];
int pp[maxn],n, m,e,ans;
bool dfs(int k){
for(int i=1;i<=n;i++)
if(d[k][i] && !b[i]){//如果這個女生沒有人選,就選
b[i]=true;//設為已選
if(!pp[i] || dfs(pp[i])){//如果這個女生有人選,就橫刀奪愛
pp[i]=k;
return true;
}
}
return false;
}
int main(){
cin>> n>>m>>e;
for(int i=0;i<e;i++){
int u,v;
cin>>u>>v;
if(u>n || v>m)//如果超界
continue;//繼續
d[u][v]=true;//設為1
}
for(int i=1;i<=m;i++){
memset(b,0,sizeof(b));//清0
if(dfs(i))//如果可以匹配
ans++;//答案加1
}
cout<<ans<<endl;
return 0;
}