题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2063
6 3 3 1 1 1 2 1 3 2 1 2 3 3 1 0
3
最简答的二分图,采用匈牙利算法;
先画个图;然后按照图我们分析一下这么题目的大概解题思路:
就是先给1号女生找男生,然后就找到了1号男生与之组队,然后我们就帮2号女生选男生,找到了1号男生,此时就和1号女生矛盾了,于是就返回看看1号女生可以和别的男生组队么,找到了2号男生,同理,3号女生也可以和1号男生组队,最后就是,1号女生和2号男生,2号女生和3号男生,3号女生和1号男生,于是就可以结束了;
具体的代码:
#include<cstdio> #include<iostream> #include<algorithm> #include<string> #include<cstring> #include<cmath> #include<math.h> #include<queue> using namespace std; #define sf scanf #define pf printf #define INF 1<<29 #define clr(x) memset(x,0,sizeof(x)) #define Clr(x) memset(x,-1,sizeof(x)); #define maxn 505 int map[maxn][maxn]; int vis[maxn]; int link[maxn]; int k,n,m; int dfs(int x){ for(int i=1;i<=m;i++){//注意这里是m if(!vis[i]&&map[x][i]){ vis[i]=1; if(!link[i]||dfs(link[i])){ link[i]=x; return true; } } } return false; } void init(){ clr(map); clr(link); } int main(){ int girl,boy,ans=0; while(EOF!=sf("%d%d%d",&k,&n,&m)&&k){ init(); for(int i=1;i<=k;i++){ sf("%d%d",&girl,&boy); map[girl][boy]=1; } ans=0; for(int i=1;i<=n;i++){//注意这里是n clr(vis); if(dfs(i)) ans++; } pf("%d\n",ans); } return 0; }