HDU 2444:The Accomodation of Students(二分图判定+匹配)
http://acm.hdu.edu.cn/showproblem.php?pid=2444
题意:给出边,判断这个是否是一个二分图,并求最大匹配。
思路:先染色法求出是否是一个二分图,然后再匈牙利求出最大匹配。注意输出是“No"而不是”NO“!!!
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <string> 7 #include <iostream> 8 #include <stack> 9 #include <map> 10 #include <queue> 11 using namespace std; 12 #define N 100010 13 #define INF 0x3f3f3f3f 14 struct node 15 { 16 int nxt, v; 17 }edge[205*105]; 18 int head[205], tot; 19 int col[205]; 20 bool vis[205]; 21 int match[205]; 22 23 void add(int u, int v) 24 { 25 edge[tot].v = v; edge[tot].nxt = head[u]; head[u] = tot++; 26 } 27 28 bool check(int u,int c) 29 { 30 col[u] = c; 31 for(int i = head[u]; ~i; i = edge[i].nxt) { 32 int v = edge[i].v; 33 if(col[v] == c) return false; 34 if(col[v] == 0 && !check(v, -c)) return false; 35 } 36 return true; 37 } 38 39 bool dfs(int u) 40 { 41 for(int i = head[u]; ~i; i = edge[i].nxt) { 42 int v = edge[i].v; 43 if(!vis[v]) { 44 vis[v] = 1; 45 if(match[v] == -1 || dfs(match[v])) { 46 match[v] = u; 47 return true; 48 } 49 } 50 } 51 return false; 52 } 53 54 int main() 55 { 56 int n, m; 57 while(~scanf("%d%d", &n, &m)) { 58 memset(match, -1, sizeof(match)); 59 memset(head, -1, sizeof(head)); 60 memset(col, 0, sizeof(col)); 61 tot = 0; 62 for(int i = 0; i < m; i++) { 63 int u, v; 64 scanf("%d%d", &u, &v); 65 add(u, v); add(v, u); 66 } 67 bool f = 1; 68 for(int i = 1; i <= n; i++) { 69 if(col[i] == 0) { 70 if(!check(i, 1)) { 71 f = 0; 72 puts("No"); 73 break; 74 } 75 } 76 } 77 if(!f) continue; 78 int sum = 0; 79 for(int i = 1; i <= n; i++) { 80 memset(vis, 0, sizeof(vis)); 81 sum += dfs(i); 82 } 83 printf("%d\n", sum / 2); 84 } 85 return 0; 86 }