zoukankan      html  css  js  c++  java
  • 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
    ",ac.dinic());
    105 }
  • 相关阅读:
    第二周学习进度总结
    《大道至简》阅读收获及个人总结
    代码层面解释安全性
    2020年大三下学期第二周学习心得
    信息化领域热词分类分析及解释实战
    2020年新型冠状病毒疫情分析实战
    《架构漫谈》个人理解概括
    北京市信件内容爬虫实例——首都之窗
    2020寒假生活学习日记(十五)
    2020寒假生活学习日记(十四)
  • 原文地址:https://www.cnblogs.com/ccsu-kid/p/11512685.html
Copyright © 2011-2022 走看看