您的位置:首页 > 其它

HDU 5285 wyh2000 and pupil (二分图着色)

2015-07-18 21:29 459 查看
题意:

  共有n个小学生,编号为1−n。将所有小学生分成2组,每组都至少有1个人。但是有些小学生之间并不认识,而且如果a不认识b,那么b也不认识a。Wyh2000希望每组中的小学生都互相认识。而且第一组的人要尽可能多。请你帮wyh2000求出第一组和第二组的人数是多少。如果找不到分组方案,则输出"Poor wyh"。

思路:

  二分图着色。给的就是无向图,每次都累加人多的颜色即可。若不能着色,必定不能分成2组。如果全部都是1个颜色,那么要让其中1人过第2组。我勒个去,就因为赭色时颜色号码开小了而错。

//#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <set>
#include <deque>
#include <algorithm>
#include <vector>
#define LL long long
#define pii pair<int,int>
#define INF 0x7f7f7f7f
using namespace std;
const int N=100000+100;

vector<int> vect
;
int col
;
set<int> mapp;

int color(int u, int f)
{
mapp.clear();
deque<int> que;
que.push_back(u);
col[u]=f;
mapp.insert(u);
while(!que.empty())
{
int x=que.front();
que.pop_front();

for(int i=0; i<vect[x].size(); i++)
{
int tmp=vect[x][i];
if(col[tmp]==col[x]) return 0;  //冲突
if(col[tmp]==0)   //没色
{
mapp.insert(tmp);//一个连同分量装进去
col[tmp]=1000000-col[x];
que.push_back(tmp);
}
}
}
return 1;
}

int cal(int n)
{
memset(col,0,sizeof(col));
int big=0, small=0, k=0;
for(int i=1; i<=n; i++)
{
if(!col[i])
{
if(!color(i, ++k)) return 0;

//统计人数
int a=0, b=0;
set<int>::iterator it=mapp.begin();
for(int j=0; j<mapp.size(); j++)
{
if(col[*it]==k)   a++;
if(col[*it]==1000000-k) b++;
it++;
}

if(a<b) swap(a, b);
big+=a;
small+=b;
}
}
if(!small)  return big-1;
else return big;
}

int main()
{
freopen("input.txt", "r", stdin);
int t, n, m, a, b;
cin>>t;
while(t--)
{
scanf("%d%d",&n,&m);
for(int i=0; i<=n; i++)    vect[i].clear();

for(int i=0; i<m; i++)
{
scanf("%d%d",&a,&b);
vect[a].push_back(b);
vect[b].push_back(a);
}
if(n<=1)
{
puts("Poor wyh");
continue;
}
else if(n==2)
{
puts("1 1");
continue;
}

int tmp=cal(n);
if(tmp) printf("%d %d\n",tmp, n-tmp);
else  puts("Poor wyh");

}
return 0;
}


AC代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: