二分图的最大匹配(模板)

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 }

 

 

#include<bits/stdc++.h>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; }

以上是关于二分图的最大匹配(模板)的主要内容,如果未能解决你的问题,请参考以下文章

二分图的判定(染色法)和二分图最大匹配(匈牙利)算法及模板

匈牙利算法,二分图的最大匹配

匈牙利算法 二分图最大匹配题模板

匈牙利算法及其模板 - [二分图最大匹配]

匈牙利算法-二分图的最大匹配

专题之匹配网络流