版权声明:如果路过的各位大佬想对菜鸡进行指点请加QQ:3360769137 https://blog.csdn.net/PleasantlY1/article/details/83116479
题目描述
曹是一只爱刷街的老曹,暑假期间,他每天都欢快地在阳光大学的校园里刷街。河蟹看到欢快的曹,感到不爽。河蟹决定封锁阳光大学,不让曹刷街。
阳光大学的校园是一张由N个点构成的无向图,N个点之间由M条道路连接。每只河蟹可以对一个点进行封锁,当某个点被封锁后,与这个点相连的道路就被封锁了,曹就无法在与这些道路上刷街了。非常悲剧的一点是,河蟹是一种不和谐的生物,当两只河蟹封锁了相邻的两个点时,他们会发生冲突。
询问:最少需要多少只河蟹,可以封锁所有道路并且不发生冲突。
输入输出格式
输入格式:
第一行:两个整数N,M
接下来M行:每行两个整数A,B,表示点A到点B之间有道路相连。
输出格式:
仅一行:如果河蟹无法封锁所有道路,则输出“Impossible”,否则输出一个整数,表示最少需要多少只河蟹。
输入输出样例
输入样例#1:
3 3 1 2 1 3 2 3
输出样例#1:
Impossible
输入样例#2:
3 2 1 2 2 3
输出样例#2:
1
说明
【数据规模】
1<=N<=10000,1<=M<=100000,任意两点之间最多有一条道路。
思路:可以转化成染色问题,相邻点颜色不同,就只有2种颜色,暴力跑出所有符合条件的颜色组合,取最小的颜色数量即可。
然后朴素点的想法,不转换成染色,就直接暴力跑每个点的相邻点,直到跑完图再取最小即可。注意组合不成立时的跳出处理。个人问题:如果遇到相邻点颜色相同就跳出返回-1,在主函数判-1输出impossible。感觉没有问题,但是却wa了一个点。不知道为什么。找时间深入研究一下。
代码如下:
#include<set>
#include<map>
#include<list>
#include<deque>
#include<cmath>
#include<queue>
#include<stack>
#include<string>
#include<vector>
#include<stdio.h>
#include<sstream>
#include<stdlib.h>
#include<string.h>
//#include<ext/rope>
#include<iostream>
#include<algorithm>
#define pi acos(-1.0)
#define INF 0x3f3f3f3f
#define per(i,a,b) for(int i=a;i<=b;++i)
#define LL long long
#define swap(a,b) {int t=a;a=b;b=t}
using namespace std;
//using namespace __gnu_cxx;
int color[2]={0},fag;
int vis[100010]={0};
vector<int>p[10001];
int dfs(int u)
{
for(int i=0;i<p[u].size();i++)//枚举链
{
int v=p[u][i];
if(vis[v]==-1)
{
vis[v]=(vis[u]+1)%2;//相邻颜色不同
color[vis[v]]++;//颜色累加
dfs(v);
}
else if(vis[u]==vis[v]) fag=1;
}
return min(color[0],color[1]+1);//寻找需要最小的颜色数量
}
int main()
{
int n,m,a,b;
cin>>n>>m;
memset(vis,-1,sizeof(vis));
per(i,1,m)
{
cin>>a>>b;
p[a].push_back(b);
p[b].push_back(a);
}
int s=0;
fag=0;
per(i,1,n)//枚举每个点
{
color[0]=0;
color[1]=0;
if(vis[i]==-1)
{
vis[i]=1;//颜色标记
s+=dfs(i);
}
}
if(fag==1) cout<<"Impossible"<<endl;
else
cout<<s;
return 0;
}