HDU 2444:The Accomodation of Students(二分图判定+匹配)

时间:2021-10-18 06:03:30

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 }