hdu 2444
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2444
题意:给出一些两两认识的学生,把这些学生分成两组,每组中的学生都不互相认识,如果可以完成,那么把他们安排进一些双人间中,每个房间中只能住相互认识的学生,如果不可以分成两组 输出 No,可以住的那么输出最多需要多少个房间
思路:求是否可以分成两组用dfs黑白染色,看给出的关系是否是一个二分图。判断房间数用则用二分匹配对无向图进行匹配,求出最大匹配数,即为房间数。感觉更像模板题,直接套用最大匹配模板就可以了
View Code
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <algorithm> 5 #define N 210 6 #define _clr(a,val) (memset(a,val,sizeof(a))) 7 8 using namespace std; 9 10 int map[N][N]; 11 int match[N]; 12 int color[N]; 13 bool vis[N]; 14 int n,flag,m; 15 void dfs(int x,int c) // dfs 黑白染色 16 { 17 for(int i = 1; i <= n; i++) 18 { 19 if(map[x][i]) 20 { 21 if(color[i] == c) continue; 22 if(color[i] == 0) 23 { 24 color[i] = c; 25 dfs(i,-c); 26 } 27 else 28 { 29 flag = 0; 30 return ; 31 } 32 if(!flag) return ; 33 } 34 } 35 } 36 int ddfs(int x) 37 { 38 int i; 39 for(i = 1; i <= n; i++) 40 { 41 if(!vis[i] && map[x][i]) 42 { 43 vis[i] = 1; 44 if(match[i] == -1 || ddfs(match[i])) 45 { 46 match[i] = x; 47 return 1; 48 } 49 } 50 } 51 return 0; 52 } 53 int getsum() 54 { 55 int i,num; 56 num = 0; 57 _clr(match,-1); 58 for(i = 1; i <= n; i++) 59 { 60 _clr(vis,0); 61 if(ddfs(i)) 62 { 63 num++; 64 } 65 } 66 return num; 67 } 68 int main() 69 { 70 int i; 71 int x,y; 72 //freopen("data.txt","r",stdin); 73 while(scanf("%d%d",&n,&m) != EOF) 74 { 75 _clr(map,0); 76 _clr(color,0); 77 for(i = 0; i < m; i++) 78 { 79 scanf("%d%d",&x,&y); 80 map[x][y] = map[y][x] = 1; 81 } 82 flag = 1; 83 color[1] = -1; 84 dfs(1,1); 85 if(!flag) 86 { 87 printf("No\n");continue; 88 } 89 int ans = getsum(); 90 printf("%d\n",ans / 2); 91 } 92 return 0; 93 }