(模板)二分圖最大匹配,最大流演算法
阿新 • • 發佈:2019-02-20
轉換為最大流做即可。注意加邊的技巧。
程式碼如下:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
struct edge{
int to,cap,rev;
};
vector<edge>G[2500];
void addedge(int from,int to,int cap)
{
G[from].push_back(edge{to,cap,(int )G[to].size()});
G[to].push_back(edge{from,0,(int)G[from].size()-1});
}
int level[2500],iter[2500];
int bfs(int s)
{
memset(level,-1,sizeof(level));level[s]=0;
queue<int>que;que.push(s);
while(!que.empty()){
int t=que.front();que.pop();
for(auto i=G[t].begin();i!=G[t].end();i++){
edge e=*i;
if (e.cap>0&&level[e.to]<0){
level[e.to]=level[t]+1;que.push(e.to);
}
}
}
}
int dfs(int v,int t,int f)
{
if(v==t)return f;
for(int&i=iter[v];i<G[v].size();i++){
edge&e=G[v][i];
if(e.cap&&level[e.to]>level[v]){
int d=dfs(e.to,t,min(e.cap,f));
if(d){
e.cap-=d;
G[e.to][e.rev].cap+=d;
return d;
}
}
}
return 0;
}
int maxflow(int s,int t)
{
int flow=0;
for(;;){
bfs(s);
if(level[t]<0)return flow;
memset(iter,0, sizeof(iter));
int f;
while(f=dfs(s,t,1<<30))
flow+=f;
}
}
int main()
{
int n,m,e,i,j,k;
cin>>n>>m>>e;
for(i=1;i<=n;i++)
addedge(0,i,1);
for(i=n+1;i<=n+m;i++)
addedge(i,2020,1);//源點為0,匯點為2020
for(i=1;i<=e;i++){
scanf("%d%d",&k,&j);
if(j>m)continue;
addedge(k,j+n,1);
}
cout<<maxflow(0,2020)<<endl;
return 0;
}