洛谷P3386 【模板】二分图匹配

题目背景

二分图

感谢@一扶苏一 提供的hack数据

题目描述

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

输入输出格式

输入格式:

第一行,n,m,e

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

输出格式:

共一行,二分图最大匹配

输入输出样例

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

说明

n,m1000, 1un, 1vm

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

算法:二分图匹配

/*
    二分图匈牙利算法模板 没什么可说的
*/

#include <bits/stdc++.h>

using namespace std;

const int maxn = 1e3+5;

inline int read() {
     int x = 0,m = 1;
     char ch;
     while(ch < '0' || ch > '9')  {if(ch == '-') m = -1;ch = getchar();}
     while(ch >= '0' && ch <= '9'){x = x * 10 + ch-'0';ch = getchar();}
     return m * x;
}//快读

vector<int> G[maxn];//vector存图 效率比前向星慢 但是好写
int link[maxn],vis[maxn],n,m,e;

bool dfs(int x){
    for(int i = 0;i < G[x].size();i++){
        int v = G[x][i];
        if(!vis[v]){
            vis[v] = 1;//记住要对这个数组置1不然会爆空间23333
            if(!link[v] || dfs(link[v])){
                link[v] = x;return true;//匈牙利算法核心代码
            }
        }
    }
    return false;
}

int main()
{
    int x,y;
    n = read(),m = read(),e = read();
    for(int i = 1;i <= e;i++){
        x = read(),y = read();
        if(x <= n && y <= m) G[x].push_back(y);//记得过滤掉不合法的状态
    }
    int ans = 0;
    for(int i = 1;i <= n;i++){
        memset(vis,0,sizeof(vis));//这里一定要记得memset
        if(dfs(i)) ans++;
    }
    printf("%d
",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/bryce02/p/9883773.html