wyh2000 and pupil
Accepts: 93
Submissions: 925
Time Limit: 3000/1500 MS (Java/Others)
Memory Limit: 131072/65536 K (Java/Others)
问题描述
青年理论计算机科学家wyh2000在教导他的小学生。 共有nnn个小学生,编号为1−n1-n1−n。为了增加小学生之间的凝聚力,wyh2000决定将所有小学生分成222组,每组都至少有111个人。 但是有些小学生之间并不认识,而且如果aaa不认识bbb,那么bbb也不认识aaa。 Wyh2000希望每组中的小学生都互相认识。而且第一组的人要尽可能多。 请你帮wyh2000求出第一组和第二组的人数是多少。如果找不到分组方案,则输出"Poor wyh"。
输入描述
第一行一个数TTT,表示数据组数。 对于每组数据,第一行两个数n,mn,mn,m,表示小学生数量和互相不认识的小学生的数量。 接下来mmm行,每行两个数x,y(x<y)x,y(x < y)x,y(x<y),表示xxx不认识yyy,yyy不认识xxx。保证一对(x,y)(x,y)(x,y)只会出现一次。 T≤10,0≤n,m≤100000T\leq10,0\leq n,m\leq100000T≤10,0≤n,m≤100000
输出描述
对于每组数据,输出答案。
输入样例
2 8 5 3 4 5 6 1 2 5 8 3 5 5 4 2 3 4 5 3 4 2 4
输出样例
5 3 Poor wyh
问题:分出两个集合、保证一组至少有一个人,并且第一组人尽量的多、
我们这里假设a和b不认识,b和c不认识,但是a和c是认识的、所以我们这里假设染色a为1,b染色为2,通过b找到c,染色c为1,那么a,c就是一个集合里边的元素。所以我们这里可以应用染色法来解决这个问题,题目中问的不是最大匹配问题,我们这里要判断整张图是不是二分图,如果不是,那么是不行的。
所以我们确定了解决问题的方法:二分+染色、
这里有两个坑,一个是n==1的时候,问题保证每个组都至少要有1个人,这个时候要输出poor,另外如果n==0的时候,也要输出poor、
这里我们直接上代码:
#include<stdio.h>
#include<iostream>
#include<vector>
#include<queue>
#include<string.h>
using namespace std;
vector<int >map[1000005];
int color[1000005];
int ans;
int bfs(int x)
{
queue<int >s;
int one=0;
int two=0;
s.push(x);
color[x]=1;
one++;
while(!s.empty())
{
int u=s.front();
s.pop();
for(int i=0;i<map[u].size();i++)
{
int v=map[u][i];
if(color[v])
{
if(color[v]==color[u])
{
return 0;
}
}
else
{
color[v]=3-color[u];
if(color[v]==1)
{
one++;
}
else
{
two++;
}
s.push(v);
}
}
}
ans+=max(one,two);
return 1;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m;
ans=0;
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++)
{
map[i].clear();
}
memset(color,0,sizeof(color));
if(n==0)
{
printf("Poor wyh\n");
continue;
}
for(int i=0;i<m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
map[x].push_back(y);
map[y].push_back(x);
}
int ok=0;
for(int i=1;i<=n;i++)
{
if(color[i]!=0)continue;
else
{
if(bfs(i)==0)
{
ok=1;
break;
}
}
}
if(ok==1)
{
printf("Poor wyh\n");
}
else
{
if(m==0)
{
if(ans==1)
{
printf("Poor wyh\n");
}
else
{
printf("%d %d\n",ans-1,1);
}
}
else
{
printf("%d %d\n",ans,n-ans);
}
}
}
}