1. 程式人生 > >匈牙利演算法2018-10-14

匈牙利演算法2018-10-14

看到這一題
或者這個
優秀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; }