原题:http://acm.hdu.edu.cn/showproblem.php?pid=2444
题意:
有n个人,m对人相互认识;
问能否分成两个组,组内任意两个人之间不认识;
若不能,则输出No;
若能,则相互认识的两个人一间房,求最多需要几间房;
#include<stdio.h>
#include<queue>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
int n, m;
const int N = 1100;
bool map[N][N];
int used[N], s[N];
int b[N];
bool find(int x)
{
for(int i = 1;i<=n;i++)
{
if(map[x][i] == true && used[i] == false)
{
used[i] = 1;
if(s[i] == 0||find(s[i]))
{
s[i] = x;
return true;
}
}
}
return false;
}
int bfs(int x)
{
queue<int>q;
q.push(x);
while(!q.empty())
{
int u = q.front();
q.pop();
for(int i = 1;i<=n;i++)
{
if(i == u || !map[u][i])
continue;
if(b[i] == -1)
{
b[i] = b[u]^1;
q.push(i);
}
else if(b[i] == b[u])
return 1;
}
}
return 0;
}
int main()
{
while(scanf("%d%d", &n, &m)!=EOF)
{
memset(map, false, sizeof(map));
memset(s, 0, sizeof(s));
int sum = 0;
for(int i = 1;i<=m;i++)
{
int x, y;
scanf("%d%d", &x, &y);
map[x][y] = map[y][x] = true;
}
memset(b, -1, sizeof(b));
int i;
for(i = 1;i<=n;i++)
{
if(b[i] == -1)
{
b[i] = 0;
if(bfs(i))
break;
}
}
if(i<=n)
{
printf("No\n");
continue;
}
for(int t = 1;t<=n;t++)
{
memset(used, 0, sizeof(used));
if(find(t))
sum++;
}
printf("%d\n", sum/2);
}
return 0;
}