hdu 5285 wyh2000 and pupil (交叉染色法,二分图点集差最大)
题目链接:hdu 5285 题目lianjie
题意:给定n个小朋友,以及小朋友之间的关系,要求将小朋友分成两组,**并且每组至少一个人,**现在问能否这样分组,如果有解,输出两组的人数,并保证第一组的人数尽可能地大。
思路:。。。一开始看到n的数据范围。。。想当然的以为会给认识的人的关系。。。尼玛。。。求个补图就够受的了。。。。不会做,卒。
结果发现。。竟然给的是两个人不认识的关系。。。2333
那么我们来交叉染色。。。
实际上交叉染色的过程中,颜色相同的点属于二分图中相同的点集合。
交叉染色其实是在模拟交错轨的过程...?
由于图不一定联通,可能由多个联通块。
我们在交叉染色的时候记录一下0,1的个数(也就是两个点集的大小)
然后每次把大的累加(因为没说不认识的就是默认认识了。。。)
无解的情况有:任何一个联通快无解或者n<=1
此外还需要注意,m可能为0.
特判一下,m为0或者为1,直接输出n-1和1.
以及!
n<=1的无解是在特判m之前的。。。。我好傻啊。
n<=1的无解是在特判m之前的。。。。我好傻啊。
n<=1的无解是在特判m之前的。。。。我好傻啊。
1/* ***********************************************
2Author :111qqz
3Created Time :2016年09月02日 星期五 14时41分35秒
4File Name :code/hdu/5285.cpp
5************************************************ */
6#include <cstdio>
7#include <cstring>
8#include <iostream>
9#include <algorithm>
10#include <vector>
11#include <queue>
12#include <set>
13#include <map>
14#include <string>
15#include <cmath>
16#include <cstdlib>
17#include <ctime>
18#define fst first
19#define sec second
20#define lson l,m,rt<<1
21#define rson m+1,r,rt<<1|1
22#define ms(a,x) memset(a,x,sizeof(a))
23typedef long long LL;
24#define pi pair < int ,int >
25#define MP make_pair
26using namespace std;
27const double eps = 1E-8;
28const int dx4[4]={1,0,0,-1};
29const int dy4[4]={0,-1,1,0};
30const int inf = 0x3f3f3f3f;
31const int M = 2E5+7;
32const int N = 1E5+7;
33int n,m;
34int head[N];
35int col[N];
36struct Edge
37{
38 int v;
39 int nxt;
40}edge[M];
41int cnt;
42int cnt0,cnt1;
43void addedge(int u ,int v)
44{
45 edge[cnt].v = v;
46 edge[cnt].nxt = head[u];
47 head[u] = cnt;
48 cnt++;
49}
50int dfs( int u,int x,int fa)
51{
52 col[u] = x;
53 if (x==0) cnt0++;else cnt1++;
54 for ( int i = head[u] ; i !=-1 ; i = edge[i].nxt)
55 {
56 int v = edge[i].v;
57 if (v==fa) continue;
58 if (col[v]==1-x) continue;
59 if (col[v]==x) return -1;
60 if (!dfs(v,1-x,u)) return -1;
61 }
62 return max(cnt0,cnt1);
63}
64int solve()
65{
66 int res = 0 ;
67 for ( int i = 1 ; i <= n ; i++)
68 {
69 if (col[i]!=-1) continue;
70 cnt0 = cnt1 = 0 ;
71 int tmp = dfs(i,0,-1);
72 if (tmp==-1) return -1;
73 res+=tmp;
74 }
75 return res;
76}
77int main()
78{
79 #ifndef ONLINE_JUDGE
80 freopen("code/in.txt","r",stdin);
81 #endif
82 int T;
83 cin>>T;
84 while (T--)
85 {
86 scanf("%d%d",&n,&m);
87 cnt = 0 ;
88 ms(head,-1);
89 ms(col,-1);
90 for ( int i = 1 ; i <= m ; i++)
91 {
92 int u,v;
93 scanf("%d%d",&u,&v);
94 addedge(u,v);
95 addedge(v,u);
96 }
97 if (n<2)
98 {
99 puts("Poor wyh");
100 continue;
101 }
102 if (m<=1)
103 {
104 printf("%d %d\n",n-1,1);
105 continue;
106 }
107 int ans = solve();
108 if (ans==-1) puts("Poor wyh");
109 else printf("%d %d\n",ans,n-ans);
110 }
111 #ifndef ONLINE_JUDGE
112 fclose(stdin);
113 #endif
114 return 0;
115}