首页 > 其他 > 详细

洛谷P1330 封锁阳光大学 [图论,染色]

时间:2018-06-09 13:47:52      阅读:192      评论:0      收藏:0      [点我收藏+]

  题目传送门

封锁阳光大学

题目描述

曹是一只爱刷街的老曹,暑假期间,他每天都欢快地在阳光大学的校园里刷街。河蟹看到欢快的曹,感到不爽。河蟹决定封锁阳光大学,不让曹刷街。

阳光大学的校园是一张由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,任意两点之间最多有一条道路。


  分析:

  思路非常巧妙的一道图论题,也是理解染色问题的一道好题。

  首先,题目并没有保证是一个连通图,但经过分析也可以知道,只要每个子连通图都满足要求即可。重点在于,题目要求每一条边的连个端点必须有且仅有一个端点被占。那么实际上也就等效于,任意两个相邻的点必须被染成不同的颜色。那么思路有了就好做了,直接深搜或者广搜都行,遍历每个子连通图判断是否可以按照该原则染色即可。具体看代码。

  Code:

 

 1 //It is made by HolseLee on 9th June 2018
 2 //Luogu.org P1330
 3 #include<bits/stdc++.h>
 4 using namespace std;
 5 const int N=1e4+7;
 6 const int M=1e5+7;
 7 bool vis[N];
 8 int n,m,head[N],size,col[N],sum[2],ans;
 9 struct Node{int to,next;}edge[M<<1];
10 inline int read()
11 {
12     char ch=getchar();int num=0;bool flag=false;
13     while(ch<0||ch>9){if(ch==-)flag=true;ch=getchar();}
14     while(ch>=0&&ch<=9){num=num*10+ch-0;ch=getchar();}
15     return flag?-num:num;
16 }
17 inline void add(int x,int y)
18 {
19     edge[++size].to=y;
20     edge[size].next=head[x];
21     head[x]=size; 
22 }
23 inline bool dfs(int u,int color)
24 {
25     if(vis[u]){
26         if(col[u]==color)return true;
27         return false;}
28     vis[u]=true;sum[col[u]=color]++;
29     bool flag=true;
30     for(int i=head[u];i!=-1;i=edge[i].next){
31         flag=flag&&dfs(edge[i].to,1-color);}
32     return flag;
33 }
34 int main()
35 {
36     memset(head,-1,sizeof(head));
37     memset(vis,false,sizeof(vis));
38     n=read();m=read();int x,y;
39     for(int i=1;i<=m;i++){
40         x=read();y=read();
41         add(x,y);add(y,x);}
42     for(int i=1;i<=n;i++){
43         if(vis[i])continue;
44         sum[0]=sum[1]=0;
45         if(!dfs(i,0)){
46             printf("Impossible");
47             return 0;}
48         ans+=min(sum[0],sum[1]);}
49     printf("%d",ans);
50     return 0;
51 }

 

洛谷P1330 封锁阳光大学 [图论,染色]

原文:https://www.cnblogs.com/cytus/p/9159200.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!