题目背景
二分图
感谢@一扶苏一 提供的hack数据
题目描述
给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数
输入输出格式
输入格式:
第一行,n,m,e
第二至e+1行,每行两个正整数u,v,表示u,v有一条连边
输出格式:
共一行,二分图最大匹配
输入输出样例
说明
n,m≤1000, 1≤u≤n, 1≤v≤m
因为数据有坑,可能会遇到 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; }