题目描述
给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数
输入输出格式
输入格式:
第一行,n,m,e
第二至e+1行,每行两个正整数u,v,表示u,v有一条连边
输出格式:
共一行,二分图最大匹配
输入输出样例
说明
n,m≤1000,1≤u≤n,1≤v≤m
因为数据有坑,可能会遇到 v>mv>m 的情况。请把 v>mv>m 的数据自觉过滤掉。
std
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int ans,mp[1001][1001],match[10001]; bool vis[10001]; int p,n,m; bool Hungary(int x){ for(int i=1;i<=m;++i){ if(!vis[i] && mp[x][i]){ vis[i]=true; if(!match[i] || Hungary(match[i])){ match[i]=x; return 1; } } } return 0; } int main() { scanf("%d%d%d",&n,&m,&p); for(int i=1;i<=p;++i) { int from,to; scanf("%d%d",&from,&to); if(from>=1&&from<=n && to>=1&&to<=p) mp[from][to]=1; } for(int i=1;i<=n;++i) { memset(vis,false,sizeof(vis)); ans+=Hungary(i); } printf("%d",ans); return 0; }
mine
#include<stdio.h> #include<string.h> using namespace std; const int MX=2001; struct Edge { int to,next; }edge[MX*MX]; bool vis[MX]; int n,m,e,cnt,first[MX*MX],match[MX]; void read(int &x) { x=0; int f=1; char ch=getchar(); while (ch<'0'||ch>'9') { if (ch=='-') f=-f; ch=getchar(); } while (ch>='0'&&ch<='9') { x=x*10+ch-48; ch=getchar(); } x*=f; } void add(int from,int to) { edge[++cnt].to=to; edge[cnt].next=first[from]; first[from]=cnt; } bool hungry(int x) { for(int i=first[x];i;i=edge[i].next) { int to=edge[i].to; if(vis[to]) continue; vis[to]=1; if(!match[to] || hungry(match[to])) { match[to]=x; return true; } } return false; } int main() { read(n),read(m),read(e); for(int i=1;i<=e;++i) { int sid1,sid2; read(sid1),read(sid2); if(sid2>m) continue; add(sid1,sid2); } int ans=0; for(int i=1;i<=n;++i) { memset(vis,0,sizeof(vis)); ans+=hungry(i); } printf("%d",ans); return 0; }