1 /*
2 二分图判定+点染色:因为有很多联通块,要对所有点二分图匹配,若不能,存在点是无法分配的,no
3 每一次二分图匹配时,将点多的集合加大最后第一个集合去
4 注意:n <= 1,no,两个集合都至少有一人;ans == n,扔一个给另一个集合
5 */
6 #include <cstdio>
7 #include <algorithm>
8 #include <cstring>
9 #include <cmath>
10 #include <string>
11 #include <vector>
12 #include <map>
13 using namespace std;
14
15 const int MAXN = 1e5 + 10;
16 const int INF = 0x3f3f3f3f;
17 vector<int> G[MAXN];
18 int col[MAXN];
19 int cnt[3];
20 int n, m;
21
22 bool DFS(int u)
23 {
24 for (int i=0; i<G[u].size (); ++i)
25 {
26 int v = G[u][i];
27 if (col[v] == -1) {
28 col[v] = 3 - col[u]; cnt[col[v]]++;
29 if (!DFS (v)) return false;
30 }
31 else if (col[v] == col[u]) return false;
32 }
33
34 return true;
35 }
36
37 void work(void)
38 {
39 memset (col, -1, sizeof (col));
40 int ans = 0;
41 for (int i=1; i<=n; ++i)
42 {
43 if (col[i] == -1)
44 {
45 col[i] = 1; cnt[1] = 1; cnt[2] = 0;
46 if (!DFS (i)) {
47 puts ("Poor wyh"); return ;
48 }
49 ans += max (cnt[1], cnt[2]);
50 }
51 }
52 if (ans == n) ans--;
53 printf ("%d %d
", ans, n - ans);
54 }
55
56 int main(void) //BestCoder Round #48 ($) 1002 wyh2000 and pupil
57 {
58 int t; scanf ("%d", &t);
59 while (t--)
60 {
61 scanf ("%d%d", &n, &m);
62 if (n <= 1) {
63 puts ("Poor wyh"); continue;
64 }
65 for (int i=1; i<=n; ++i) G[i].clear ();
66 for (int i=1; i<=m; ++i)
67 {
68 int u, v; scanf ("%d%d", &u, &v);
69 G[u].push_back (v); G[v].push_back (u);
70 }
71 work ();
72 }
73
74
75 return 0;
76 }
1 /* 2 并查集:有点像POJ食物链的做法, 分为(1, n)和(n+1, 2*n)两个集合,两种情况都试一下。 3 rt[i] == -1表示是该集合的根,用sz数组记录集合的大小 4 */ 5 #include <cstdio> 6 #include <algorithm> 7 #include <cstring> 8 #include <cmath> 9 #include <string> 10 #include <vector> 11 #include <map> 12 using namespace std; 13 14 const int MAXN = 1e5 + 10; 15 const int INF = 0x3f3f3f3f; 16 int n, m; 17 struct UF { 18 int rt[MAXN*2], sz[MAXN*2], sz2[MAXN*2]; 19 void init(void) { 20 memset (rt, -1, sizeof (rt)); 21 for (int i=1; i<=2*n; ++i) sz[i] = (i <= n), sz2[i] = (i > n); 22 } 23 int Find(int x) { 24 return rt[x] == -1 ? x : rt[x] = Find (rt[x]); 25 } 26 void Union(int x, int y) { 27 x = Find (x); y = Find (y); 28 if (x == y) return ; 29 rt[x] = y; 30 sz[y] += sz[x]; sz2[y] += sz2[x]; 31 } 32 bool same(int x, int y) { 33 return Find (x) == Find (y); 34 } 35 }uf; 36 37 int main(void) //BestCoder Round #48 ($) 1002 wyh2000 and pupil 38 { 39 int t; scanf ("%d", &t); 40 while (t--) 41 { 42 scanf ("%d%d", &n, &m); 43 bool ok = true; uf.init (); 44 for (int i=1; i<=m; ++i) 45 { 46 int u, v; scanf ("%d%d", &u, &v); 47 if (!ok) continue; 48 if (uf.same (u, v) || uf.same (u+n, v+n)) ok = false; 49 else uf.Union (u, v+n), uf.Union (u+n, v); 50 } 51 52 if (!ok || n <= 1) puts ("Poor wyh"); 53 else if (m == 0) printf ("%d 1 ", n - 1); 54 else { 55 int ans = 0; 56 for (int i=1; i<=n; ++i) { 57 if (uf.rt[i] == -1) { 58 ans += min (uf.sz[i], uf.sz2[i]); 59 } 60 } 61 printf ("%d %d ", n - ans, ans); 62 } 63 } 64 65 return 0; 66 }