【二分图】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<iostream> #include<cstdio> #include<cstring> using namespace std; int n,m,k,x,y,ans; bool map[1001][1001],used[1001]; int point[1001]; bool find(int a) { for(int i=0;i<=m;++i) { if(!used[i]&&map[a][i]) { used[i]=1; if(point[i]==0||find(point[i])) { point[i]=a; return true; } } } return false; } int main() { scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=k;++i) { scanf("%d%d",&x,&y); if(x>m||y>m)continue; map[x][y]=1; } for(int i=1;i<=n;++i) { memset(used,0,sizeof(used)); if(find(i))ans++; } printf("%d",ans); }
邻接表:
#include<cstdio> #include<iostream> #include<cstring> using namespace std; struct edge{ int y,ne; }e[1000001]; int n,m,x,y,k,ans,ecnt; int head[2010],point[2010]; bool used[2010]; void add(int a,int b) { e[++ecnt].y=b; e[ecnt].ne=head[a]; head[a]=ecnt; } bool find(int a) { for(int i=head[a];i;i=e[i].ne) { if(!used[e[i].y]) { used[e[i].y]=1; if(point[e[i].y]==0||find(point[e[i].y])) { point[e[i].y]=a; return true; } } } return false; } int main() { scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=k;++i) { scanf("%d%d",&x,&y); if(y<=m&&x<=m) { add(x,y); } } for(int i=1;i<=n;++i) { memset(used,0,sizeof(used)); if(find(i))ans++; } printf("%d",ans); }