题目描述
曹是一只爱刷街的老曹,暑假期间,他每天都欢快地在阳光大学的校园里刷街。河蟹看到欢快的曹,感到不爽。河蟹决定封锁阳光大学,不让曹刷街。
阳光大学的校园是一张由N个点构成的无向图,N个点之间由M条道路连接。每只河蟹可以对一个点进行封锁,当某个点被封锁后,与这个点相连的道路就被封锁了,曹就无法在与这些道路上刷街了。非常悲剧的一点是,河蟹是一种不和谐的生物,当两只河蟹封锁了相邻的两个点时,他们会发生冲突。
询问:最少需要多少只河蟹,可以封锁所有道路并且不发生冲突。
输入输出格式
输入格式:
第一行:两个整数N,M
接下来M行:每行两个整数A,B,表示点A到点B之间有道路相连。
输出格式:
仅一行:如果河蟹无法封锁所有道路,则输出“Impossible”,否则输出一个整数,表示最少需要多少只河蟹。
输入输出样例
输入样例#1:
【输入样例1】
3 3
1 2
1 3
2 3
【输入样例2】
3 2
1 2
2 3
输出样例#1:
【输出样例1】
Impossible
【输出样例2】
1
说明
【数据规模】
1<=N<=10000,1<=M<=100000,任意两点之间最多有一条道路。
【分析】
二分图染色裸题
注意图不连通的情况
【代码】
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<vector>
#define ll long long
#define fo(i,j,k) for(i=j;i<=k;i++)
using namespace std;
int ans=0;
queue <int> q;
vector <int> f[10005];
int color[10005],sum[3];
inline bool bfs(int x)
{
int i,j,u,v;
while(!q.empty()) q.pop();
q.push(x);
memset(sum,0,sizeof sum);
color[x]=1;sum[1]++;
while(!q.empty())
{
u=q.front();
q.pop();
int t=f[u].size()-1;
fo(i,0,t)
{
v=f[u][i];
if(color[v]==color[u]) return 0;
if(!color[v])
{
q.push(v);
if(color[u]==1) color[v]=2,sum[2]++;
else color[v]=1,sum[1]++;
}
}
}
ans+=min(sum[1],sum[2]);
return 1;
}
int main()
{
int i,j,k,n,m,u,v;
scanf("%d%d",&n,&m);
while(m--)
{
scanf("%d%d",&u,&v);
f[u].push_back(v);
f[v].push_back(u);
}
fo(i,1,n)
if(!color[i])
if(!bfs(i))
{
printf("Impossible\n");
return 0;
}
printf("%d\n",ans);
return 0;
}