zoukankan      html  css  js  c++  java
  • AC日记——【模板】二分图匹配 洛谷 P3386

    题目背景

    二分图

    题目描述

    给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数

    输入输出格式

    输入格式:

    第一行,n,m,e

    第二至e+1行,每行两个正整数u,v,表示u,v有一条连边

    输出格式:

    共一行,二分图最大匹配

    输入输出样例

    输入样例#1:
    1 1 1
    1 1
    输出样例#1:
    1

    说明

    n,m<=1000,1<=u<=n,1<=v<=m

    因为数据有坑,可能会遇到v>m的情况。请把v>m的数据自觉过滤掉。

    算法:二分图匹配

    思路:

      二分图模板;

    来,上代码:

    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    #define maxn 1005
    #define INF 0x7fffffff
    
    using namespace std;
    
    struct EdgeType {
        int v,f,e;
    };
    struct EdgeType edge[maxn*maxn*2];
    
    int cnt,deep[maxn<<1],ans,e;
    int n,m,head[maxn<<1],s=0,t=(maxn<<1)-1;
    
    char Cget;
    
    inline void in(int &now)
    {
        now=0,Cget=getchar();
        while(Cget>'9'||Cget<'0') Cget=getchar();
        while(Cget>='0'&&Cget<='9')
        {
            now=now*10+Cget-'0';
            Cget=getchar();
        }
    }
    
    bool bfs()
    {
        for(int i=s;i<=t;i++) deep[i]=-1;
        queue<int>que;deep[s]=0,que.push(s);
        while(!que.empty())
        {
            int now=que.front();que.pop();
            for(int i=head[now];i;i=edge[i].e)
            {
                if(edge[i].f>0&&deep[edge[i].v]<0)
                {
                    deep[edge[i].v]=deep[now]+1;
                    if(edge[i].v==t) return true;
                    que.push(edge[i].v);
                }
            }
        }
        return false;
    }
    
    int flowing(int now,int flow)
    {
        if(now==t||flow<=0) return flow;
        int oldflow=0;
        for(int i=head[now];i;i=edge[i].e)
        {
            if(edge[i].f<=0||deep[edge[i].v]!=deep[now]+1) continue;
            int pos=flowing(edge[i].v,min(edge[i].f,flow));
            if(pos>0)
            {
                flow-=pos;
                oldflow+=pos;
                edge[i].f-=pos;
                edge[i^1].f+=pos;
                if(flow==0) return oldflow;
            }
        }
        if(oldflow==0) deep[now]=-1;
        return oldflow;
    }
    
    int main()
    {
        in(n),in(m),in(e);
        for(int i=1;i<=n;i++)
        {
            edge[++cnt].v=i,edge[cnt].f=1,edge[cnt].e=head[s],head[s]=cnt;
            edge[++cnt].v=s,edge[cnt].f=0,edge[cnt].e=head[i],head[i]=cnt;
        }
        for(int i=1+n;i<=m+n;i++)
        {
            edge[++cnt].v=t,edge[cnt].f=1,edge[cnt].e=head[i],head[i]=cnt;
            edge[++cnt].v=i,edge[cnt].f=0,edge[cnt].e=head[t],head[t]=cnt;
        }
        int u,v;
        while(e--)
        {
            in(u),in(v);v+=n;
            edge[++cnt].v=v,edge[cnt].f=1,edge[cnt].e=head[u],head[u]=cnt;
            edge[++cnt].v=u,edge[cnt].f=0,edge[cnt].e=head[v],head[v]=cnt;
        }
        while(bfs()) ans+=flowing(s,INF);
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    计算器程序
    输入三个整数,输出最大数和最小数
    输入三个数a,b,c,要示按由小到大的顺序输出
    最短路
    luogu P3953 逛公园
    二分图匹配
    luogu P3231 消毒
    [bzoj2120] [洛谷P1903] 数颜色
    [bzoj2038] [洛谷P1494] [2009国家集训队] 小Z的袜子(hose)
    [洛谷P4012] [网络流24题] 深海机器人问题
  • 原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/6648368.html
Copyright © 2011-2022 走看看