二分图的最大匹配(模板)
Posted 1129-tangqiyuan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分图的最大匹配(模板)相关的知识,希望对你有一定的参考价值。
传送门:https://www.luogu.org/problem/P3386
已经加入极其简单的当前弧优化
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,m,bian,s,t; 4 int dep[6000001]; 5 int inque[6000001]; 6 int cur[6000001]; 7 int maxflow=0; 8 struct edge{ 9 int to,nxt,flow; 10 }e[6000001];int tot=-1; 11 int first[6000001]; 12 const int inf=0x3f3f3f3f; 13 inline int kd() 14 { 15 int x=0,f=1;char ch=getchar(); 16 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} 17 while(ch>=‘0‘&&ch<=‘9‘){x=x*10+(ch^48);ch=getchar();} 18 return x*f; 19 } 20 inline void add_edge(int a,int b,int c) 21 { 22 e[++tot].to=b; 23 e[tot].flow=c; 24 e[tot].nxt=first[a]; 25 first[a]=tot; 26 } 27 bool bfs() 28 { 29 for(register int i=0;i<=n+m+2;i++)cur[i]=first[i],inque[i]=false,dep[i]=0x3f3f3f3f; 30 dep[s]=0; 31 queue<int>q; 32 q.push(s); 33 while(q.empty()==false) 34 { 35 int now=q.front(); 36 q.pop(); 37 inque[now]=false; 38 for(int i=first[now];i!=-1;i=e[i].nxt) 39 { 40 int to=e[i].to; 41 if(dep[now]+1<dep[to]&&e[i].flow!=0) 42 { 43 dep[to]=dep[now]+1; 44 if(inque[to]==false) 45 { 46 inque[to]=true; 47 q.push(to); 48 } 49 } 50 } 51 } 52 if(dep[t]==0x3f3f3f3f)return false; 53 return true; 54 } 55 int dfsl(int now,int nowflow) 56 { 57 int rlow=0; 58 if(now==t) 59 { 60 maxflow+=nowflow; 61 return nowflow; 62 } 63 int used=0; 64 for(int i=cur[now];i!=-1;i=e[i].nxt) 65 { 66 cur[now]=i; 67 if(dep[now]+1==dep[e[i].to]&&e[i].flow!=0) 68 { 69 if(rlow=dfsl(e[i].to,min(nowflow,e[i].flow))) 70 { 71 used+=rlow; 72 e[i].flow-=rlow; 73 e[i^1].flow+=rlow; 74 if(used==nowflow)return nowflow; 75 } 76 } 77 } 78 if(used==0)dep[now]=0x3f3f3f3f; 79 return used; 80 } 81 void dinic() 82 { 83 while(bfs()) 84 { 85 dfsl(s,inf); 86 } 87 return; 88 } 89 int main() 90 { 91 memset(first,-1,sizeof(first)); 92 n=kd(),m=kd(),bian=kd(),s=0,t=m+n+1; 93 for(int i=1;i<=n;i++) 94 { 95 add_edge(s,i,1); 96 add_edge(i,s,0); 97 } 98 for(int i=1;i<=bian;i++) 99 { 100 int a=kd(),b=kd(); 101 if(a>n||b>m)continue; 102 add_edge(a,b+n,1); 103 add_edge(b+n,a,0); 104 } 105 for(int i=1;i<=m;i++) 106 { 107 add_edge(i+n,t,1); 108 add_edge(t,i+n,0); 109 } 110 dinic(); 111 cout<<maxflow<<endl; 112 }
usingnamespacestd; int n,m,bian,s,t; int dep[6000001]; int inque[6000001]; int cur[6000001]; int maxflow=0; struct edge{int to,nxt,flow; }e[6000001];int tot=-1; int first[6000001]; constint inf=0x3f3f3f3f; inline int kd() { int x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+(ch^48);ch=getchar();} return x*f; } inline void add_edge(int a,int b,int c) { e[++tot].to=b; e[tot].flow=c; e[tot].nxt=first[a]; first[a]=tot; } bool bfs() { for(registerint i=0;i<=n+m+2;i++)cur[i]=first[i],inque[i]=false,dep[i]=0x3f3f3f3f; dep[s]=0; queue<int>q; q.push(s); while(q.empty()==false) { int now=q.front(); q.pop(); inque[now]=false; for(int i=first[now];i!=-1;i=e[i].nxt) { int to=e[i].to; if(dep[now]+1<dep[to]&&e[i].flow!=0) { dep[to]=dep[now]+1; if(inque[to]==false) { inque[to]=true; q.push(to); } } } } if(dep[t]==0x3f3f3f3f)returnfalse; returntrue; } int dfsl(int now,int nowflow) { int rlow=0; if(now==t) { maxflow+=nowflow; return nowflow; } int used=0; for(int i=cur[now];i!=-1;i=e[i].nxt) { cur[now]=i; if(dep[now]+1==dep[e[i].to]&&e[i].flow!=0) { if(rlow=dfsl(e[i].to,min(nowflow,e[i].flow))) { used+=rlow; e[i].flow-=rlow; e[i^1].flow+=rlow; if(used==nowflow)return nowflow; } } } if(used==0)dep[now]=0x3f3f3f3f; return used; } void dinic() { while(bfs()) { dfsl(s,inf); } return; } int main() { memset(first,-1,sizeof(first)); n=kd(),m=kd(),bian=kd(),s=0,t=m+n+1; for(int i=1;i<=n;i++) { add_edge(s,i,1); add_edge(i,s,0); } for(int i=1;i<=bian;i++) { int a=kd(),b=kd(); if(a>n||b>m)continue; add_edge(a,b+n,1); add_edge(b+n,a,0); } for(int i=1;i<=m;i++) { add_edge(i+n,t,1); add_edge(t,i+n,0); } dinic(); cout<<maxflow<<endl; }
以上是关于二分图的最大匹配(模板)的主要内容,如果未能解决你的问题,请参考以下文章