洛谷P1330-封锁阳光大学(染色问题)

版权声明:如果路过的各位大佬想对菜鸡进行指点请加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;
}

猜你喜欢

转载自blog.csdn.net/PleasantlY1/article/details/83116479