P3386 【模板】二分图匹配(dinic求二分图最大匹配)

https://www.luogu.org/problem/P3386

将源点1与左边点相连,左边点与右边点相连,右边点与汇点n1+n2+2相连,跑一遍dinic的结果即为最大匹配数。

  1 #define bug(x) cout<<#x<<" is "<<x<<endl
  2 #define IO std::ios::sync_with_stdio(0)
  3 #include <bits/stdc++.h>
  4 #define iter ::iterator
  5 #define pa pair<int,int>
  6 using namespace  std;
  7 #define ll long long
  8 #define mk make_pair
  9 #define pb push_back
 10 #define se second
 11 #define fi first
 12 #define ls o<<1
 13 #define rs o<<1|1
 14 ll mod=998244353;
 15 const int inf=2e9+10;
 16 const int N=5e3+5,M=1e6+5;
 17 struct node{
 18     int cnt;
 19     int head[N];
 20     int nex[M];
 21     int W[M];
 22     int V[M];
 23     int dep[N];
 24     int cur[N];
 25     int n,s,t;
 26     void init(){
 27         cnt=-1;
 28         memset(head,-1,sizeof(head));
 29         memset(nex,-1,sizeof(nex));
 30     }
 31     void _add(int u,int v,int w){
 32         cnt++;
 33         nex[cnt]=head[u];
 34         head[u]=cnt;
 35         V[cnt]=v;
 36         W[cnt]=w;
 37     }
 38     void add(int u,int v,int w){
 39         _add(u,v,w);
 40         _add(v,u,0);
 41     }
 42     int dfs(int u,int flow){
 43         if(u==t)return flow;
 44         for(int i=cur[u];i!=-1;i=nex[i]){
 45             if((dep[V[i]])==dep[u]+1&&W[i]){
 46                 int di=dfs(V[i],min(flow,W[i]));
 47                 if(di>0){
 48                     W[i]-=di;
 49                     W[i^1]+=di;
 50                     return di;
 51                 }
 52             }
 53         }
 54         return 0;
 55     }
 56     int bfs(){
 57         queue<int>q;
 58         memset(dep,0,sizeof(dep));
 59         dep[s]=1;
 60         q.push(s);
 61         while(!q.empty()){
 62             int u=q.front();
 63             q.pop();
 64             for(int i=head[u];i!=-1;i=nex[i]){
 65                 if(!dep[V[i]]&&W[i]>0){
 66                     dep[V[i]]=dep[u]+1;
 67                     q.push(V[i]);
 68                 }
 69             }
 70         }
 71         if(dep[t]>0)return 1;
 72         return 0;
 73     }
 74     int dinic(){
 75         int res=0;
 76         while(bfs()){
 77             for(int i=1;i<=n;i++)cur[i]=head[i];
 78             while(int d=dfs(s,inf))res+=d;
 79         }
 80         return res;
 81     }
 82 }ac;
 83 int main(){
 84     int n1,n2,m;
 85     scanf("%d%d%d",&n1,&n2,&m);
 86     int s=1,t=n1+n2+2;
 87     ac.init();
 88     ac.n=n1+n2+2;
 89     ac.s=s;
 90     ac.t=t;
 91     for(int i=1;i<=n1;i++){
 92         ac.add(1,i+1,1);
 93     }
 94     for(int i=1;i<=m;i++){
 95         int x,y;
 96         scanf("%d%d",&x,&y);
 97         if(x<=n1&&y<=n2){
 98             ac.add(x+1,y+n1+1,1);
 99         }
100     }
101     for(int i=1;i<=n2;i++){
102         ac.add(i+n1+1,t,1);
103     }
104     printf("%d\n",ac.dinic());
105 }

 

posted @ 2019-09-12 16:43  Venux  阅读(422)  评论(0编辑  收藏  举报