题目链接:
题目描述:
n个小朋友要被分成两班,但是有些小朋友之间是不认得的,所以规定不能把不认识的小朋友分在一个班级里面,并且一班的人数要比二班的人数多,每个班的人数都大于零。
解题思路:
hdu给出的题解是二分图匹配加上贪心,就不多说了。
还可以用bfs对节点染色,建好图后,对节点进行bfs分成,偶数成与奇数成染成不同的颜色,颜色相同的节点都可以分到同一个集合里面,但是要判断一下奇环,如果出现奇环的话,是无法进行分组的。在每次bfs的时候再加上贪心累计求和。
1 #include <queue> 2 #include <vector> 3 #include <cstdio> 4 #include <cstring> 5 #include <iostream> 6 #include <algorithm> 7 using namespace std; 8 const int maxn = 100010; 9 vector < int > G[maxn]; 10 11 int x, y, n, m, vis[maxn], flag; 12 void bfs (int s) 13 { 14 int p, q, zreo, one, num; 15 queue <int> Q; 16 zreo = 1; 17 one = vis[s] = 0; 18 Q.push(s); 19 while (!Q.empty()) 20 { 21 p = Q.front(); 22 Q.pop(); 23 num = (vis[p] + 1) % 2; 24 for (int i=0; i<G[p].size(); i++) 25 { 26 q = G[p][i]; 27 if (vis[q]!=-1 && num != vis[q]) 28 flag = 1; 29 if (vis[q]==-1) 30 { 31 Q.push(q); 32 vis[q] = num; 33 if (num == 0) 34 zreo ++; 35 else 36 one ++; 37 } 38 } 39 } 40 x += max (zreo, one); 41 y += min (one, zreo); 42 } 43 int main () 44 { 45 int t; 46 scanf ("%d", &t); 47 while (t --) 48 { 49 scanf ("%d %d", &n, &m); 50 memset (vis, -1, sizeof(vis)); 51 for (int i=0; i<=n; i++) 52 G[i].clear(); 53 x = y = flag = 0; 54 while (m --) 55 { 56 int a, b; 57 scanf ("%d %d", &a, &b); 58 G[a].push_back (b); 59 G[b].push_back (a); 60 } 61 for (int i=1; i<=n; i++) 62 { 63 if (vis[i] == -1) 64 bfs (i); 65 if (flag) 66 break; 67 } 68 if (x == n) 69 { 70 x --; 71 y ++; 72 } 73 if (flag || x < 1 || y < 1) 74 printf ("Poor wyh\n"); 75 else 76 printf ("%d %d\n", x, y); 77 } 78 return 0; 79 }
时间: 2024-10-18 02:43:03