AC日记——模板二分图匹配 洛谷 P3386

Posted Only U - IU

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
}

 

以上是关于AC日记——模板二分图匹配 洛谷 P3386的主要内容,如果未能解决你的问题,请参考以下文章

二分图匹配([洛谷]P3386 模板 二分图匹配)

洛谷—— P3386 模板二分图匹配

洛谷P3386模板二分图匹配

洛谷 p3386模板-二分图匹配(图论)

洛谷P3386 模板二分图匹配

洛谷P3386——二分图匹配