题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2444
题意:有n个学生,m个关系,但是如果a认识b,b认识c,但是a不一定认识c;
求能不能把这n个人分成两个房间,每个房间的人互相都不认识,这就是让我们判断是不是二分图了,可以用涂色法来进行判断;
如果是二分图则求出来最大匹配是多少;
可以把两个房间的人分成两个数组也可以不分让结果除以2就行了
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; #define N 210 int maps[N][N], vis[N], used[N], n, ans, p, q; int color[N];///利用涂色法判断是否为二分图; bool Find(int u) { for(int i=1; i<=n; i++) { int x = i; if(!vis[x] && maps[u][x]) { vis[x] = 1; if(!used[x] || Find(used[x])) { used[x] = u; return true; } } } return false; } int main() { int m; int x, y, flag; while(scanf("%d %d", &n, &m)!=EOF) { flag = 0; p = q = 0; memset(color, 0, sizeof(color)); memset(maps, 0, sizeof(maps)); memset(used, 0, sizeof(used)); for(int i=1; i<=m; i++) { scanf("%d%d", &x, &y); maps[x][y] = maps[y][x] = 1; if(color[x]==0 && color[y]==0) { color[x] = 1; color[y] = -1; } else if(color[x]!=0 && color[y]==0) color[y] = -color[x]; else if(color[x]==0 && color[y]!=0) color[x] = -color[y]; else if(color[x]==color[y] && color[x]!=0) flag=1; } if(flag==1) { printf("No "); continue; } int ans = 0; for(int i=1; i<=n; i++) { memset(vis, 0, sizeof(vis)); if(Find(i)) ans++; } printf("%d ", ans/2);///因为最终会存入1-2和2-1,所以要除以二; } return 0; }