P3386 【模板】二分圖最大匹配
阿新 • • 發佈:2022-01-13
建立原點,向左部連容量為 \(1\) 的邊,二分圖上的邊容量為 \(1\),右部向匯點連容量為 \(1\) 的邊。
最大流即可。正確性顯然。
YJX AK IOI#include<bits/stdc++.h> using namespace std; #define int long long const int maxn=1005,INF=0x3f3f3f3f3f3f3f3f; struct edge{ int from,to,cap,flow; edge(){ } edge(int a,int b,int c,int d):from(a),to(b),cap(c),flow(d){ } }; struct Dinic{//net flow vector<edge> G; vector<int> e[maxn]; int d[maxn],vis[maxn],cur[maxn]; int s,t; int n,m; void addedge(int f,int t,int c){ G.push_back((edge){f,t,c,0}); G.push_back((edge){t,f,0,0}); e[t].push_back(G.size()-1); e[f].push_back(G.size()-2); } bool BFS(){ d[s]=0; memset(vis,0,sizeof(vis)); queue<int> q; vis[s]=1; q.push(s); while(!q.empty()){ int u=q.front(); q.pop(); for(int i=0;i<e[u].size();i++){ edge &k=G[e[u][i]]; if(!vis[k.to]&&k.cap>k.flow){ q.push(k.to); vis[k.to]=1; d[k.to]=d[u]+1; } } } return vis[t]; } int DFS(int u,int lst){ if(u==t||lst==0)return lst; int flow=0,f; for(int &i=cur[u];i<e[u].size();i++){ edge &k=G[e[u][i]]; if(d[k.to]==d[k.from]+1&&(f=DFS(k.to,min(lst,k.cap-k.flow)))>0){ k.flow+=f; flow+=f; lst-=f; G[e[u][i]^1].flow-=f; if(lst==0)break; } } return flow; } int flow(){ int F=0,res=0; while(BFS()){ memset(cur,0,sizeof(cur)); res+=DFS(s,INF); } return res; } }D; signed main(){ int n,m; cin>>n>>m; D.n=n+m;cin>>D.m; for(int i=1;i<=D.m;i++){ int u,v; cin>>u>>v; D.addedge(u,v+n,1); } for(int i=1;i<=n;i++)D.addedge(0,i,1); for(int i=1;i<=m;i++)D.addedge(i+n,D.n+1,1); D.s=0,D.t=D.n+1; cout<<D.flow(); return 0; }