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 ",ac.dinic()); 105 }