题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5285
题意:
这是BestCoder Round #48 里的第二题, 有汉语题意, 链接:http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=609&pid=1002
分析:
要求把学生分成两组, 给出学生不能分在一组;把给出的学生看成一条边,所以想到判断当前给出的图是否是一个二分图。判断一个图是否是一个二分图,经典的方法就给图的节点染色, 看能否用两种颜色不重合把图中节点全部染色, 如果有一个节点染了两种颜色, 就说明不是一个二分图。
这道题需要注意的是给出的图不一定是连同的, 还有就是每组最少分一个人。 知道这些就可以AC了。
#include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 100005;
vector<int> G[maxn];
int vis[maxn];
int c, cc;
bool dfs(int u, int t)
{
if(vis[u])
{
if(vis[u] == t)
return true;
return false;
}
if(t == 1)
c++;
else
cc++;
vis[u] = t;
for(int i = 0; i < G[u].size(); i++)
{
int v = G[u][i];
if(!dfs(v, -t))
return false;
}
return true;
}
int main()
{
int T, n, m, a, b;
scanf("%d", &T);
while(T--)
{
scanf("%d%d", &n, &m);
for(int i = 0; i <= n; i++)
G[i].clear();
while(m--)
{
scanf("%d%d", &a, &b);
G[a].push_back(b);
G[b].push_back(a);
}
if(n < 2)
{
puts("Poor wyh");
continue;
}
memset(vis, 0, sizeof(vis));
bool flag = true;
c = cc = 0;
int s =0, ss = 0;
for(int i = 1; i <= n; i++)
if(!vis[i])
{
s += max(c, cc);
ss += min(c, cc);
c = cc = 0;
if(!dfs(i, 1))
{
flag = false;
break;
}
}
s += max(c, cc);
ss += min(c, cc);
if(flag)
{
if(ss == 0)
ss++, s--;
printf("%d %d\n", s, ss);
}
else
puts("Poor wyh");
}
return 0;
}