洛谷 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的数据自觉过滤掉。

算法:二分图匹配

 

网络流 最大流

Dinic水过

RE了无数次

一定开大数组!!

屠龙宝刀点击就送

#include <cstdio>
#include <queue>
using namespace std;
#define Max 1000000
#define inf 1e9
struct edge
{
    int to,next,dis;
}edge[Max*5];
int ans,head[Max*5],cnt=1,dep[Max*2],n,m,e;
void add(int u,int v,int l)
{
    edge[++cnt].next=head[u];
    edge[cnt].to=v;
    edge[cnt].dis=l;
    head[u]=cnt;
}
bool bfs(int s,int t)
{
    queue<int>q;
    for(int i=s;i<=t;++i) dep[i]=inf;
    dep[s]=0;
    q.push(s);
    while(!q.empty())
    {
        int tp=q.front();
        q.pop();
        for(int i=head[tp];i;i=edge[i].next)
        {
            if(dep[edge[i].to]>dep[tp]&&edge[i].dis>0)
            {
                dep[edge[i].to]=dep[tp]+1;
                if(edge[i].to==t) return 1;
                q.push(edge[i].to);
            }
        }
    }
    return 0;
}
int dfs(int now,int t,int came_flow)
{
    if(now==t||came_flow<=0) return came_flow;
    int res=0,f;
    for(int i=head[now];i;i=edge[i].next)
    {
        if(dep[edge[i].to]==dep[now]+1&&edge[i].dis>0&&(f=dfs(edge[i].to,t,min(edge[i].dis,came_flow))))
        {
            edge[i].dis-=f;
            edge[i^1].dis+=f;
            res+=f;
            came_flow-=f;
            if(came_flow<=0) break;
        }
    }
    return res;
}
int dinic(int s,int t)
{
    while(bfs(s,t)) ans+=dfs(s,t,inf);
    return ans;
}
int main()
{
    scanf("%d%d%d",&n,&m,&e);
    for(int u,v;e--;)
    {
        scanf("%d%d",&u,&v);
        if(u<=n&&v<=m)
        {
            add(u,v+n,1);
            add(v+n,u,0);
        }
    }
    for(int i=1;i<=n;++i)
    add(0,i,1),add(i,0,0);
    for(int i=n+1;i<=m+n;++i)
    add(i,m+n+1,1),add(m+n+1,i,0);
    printf("%d",dinic(0,m+n+1));
    return 0;
}

 

posted @ 2017-03-31 19:50  杀猪状元  阅读(184)  评论(0编辑  收藏  举报