首页 > 代码库 > P1330 封锁阳光大学(染色问题)
P1330 封锁阳光大学(染色问题)
P1330 封锁阳光大学
题目描述
曹是一只爱刷街的老曹,暑假期间,他每天都欢快地在阳光大学的校园里刷街。河蟹看到欢快的曹,感到不爽。河蟹决定封锁阳光大学,不让曹刷街。
阳光大学的校园是一张由N个点构成的无向图,N个点之间由M条道路连接。每只河蟹可以对一个点进行封锁,当某个点被封锁后,与这个点相连的道路就被封锁了,曹就无法在与这些道路上刷街了。非常悲剧的一点是,河蟹是一种不和谐的生物,当两只河蟹封锁了相邻的两个点时,他们会发生冲突。
询问:最少需要多少只河蟹,可以封锁所有道路并且不发生冲突。
输入输出格式
输入格式:
第一行:两个整数N,M
接下来M行:每行两个整数A,B,表示点A到点B之间有道路相连。
输出格式:
仅一行:如果河蟹无法封锁所有道路,则输出“Impossible”,否则输出一个整数,表示最少需要多少只河蟹。
输入输出样例
输入样例#1:
【输入样例1】3 31 21 32 3【输入样例2】3 21 22 3
输出样例#1:
【输出样例1】Impossible【输出样例2】1
说明
【数据规模】
1<=N<=10000,1<=M<=100000,任意两点之间最多有一条道路。
因为河蟹很不和谐,相邻的点是不能有河蟹的,也就是相邻的点的状态不能相同,这个问题就是染色问题:
对于一个点,可以它染成黑色或者白色,所以从第一个可染色的点开始染色,将它染成黑的或者是白的,之后搜索将整张图都染色,统计被染色的黑色总数和白色总数,在两者中取min即是最小放河蟹的数目。
注意:1、由于图不一定是联通的,搜索多次。2、M<=100000,开200000,双向建边,QAQ。
1 #include<cstdio> 2 #include<queue> 3 #include<cstdlib> 4 #include<algorithm> 5 using namespace std; 6 7 const int MAXN = 10100; 8 struct Edge{ 9 int to,nxt;10 }e[200100]; //双向边乘2 11 int col[MAXN],head[MAXN];12 int n,m,cnt,ans;13 queue<int>q;14 15 void add(int u,int v)16 {17 ++cnt;18 e[cnt].to = v;19 e[cnt].nxt = head[u];20 head[u] = cnt;21 }22 23 int bfs(int a)24 {25 int ans1 = 0, ans2 = 0;26 col[a] = 1;27 ans1++;28 q.push(a); 29 while (!q.empty())30 {31 int u = q.front();32 q.pop();33 for (int i=head[u]; i; i=e[i].nxt)34 {35 int v = e[i].to;36 if (col[v]==0) 37 {38 if (col[u]==1) col[v] = 2, ans2++;39 else if (col[u]==2) col[v] = 1, ans1++;40 q.push(v);41 }42 else if (col[v]==col[u])43 {44 printf("Impossible");45 exit(0);46 }47 }48 }49 return min(ans1,ans2);50 }51 52 int main()53 {54 scanf("%d%d",&n,&m);55 for (int x,y,i=1; i<=m; ++i)56 {57 scanf("%d%d",&x,&y);58 add(x,y);59 add(y,x);60 }61 for (int i=1; i<=n; ++i)62 if (!col[i]) ans += bfs(i);63 printf("%d",ans);64 return 0;65 }
dfs代码简短一些,注意第29行。
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 5 const int MAXN = 10100; 6 struct Edge{ 7 int to,nxt; 8 }e[200100]; //双向边乘2 9 int col[MAXN],head[MAXN];10 bool vis[MAXN],flag = true; 11 int n,m,cnt,ans,ans1,ans2;12 13 void add(int u,int v)14 {15 ++cnt;16 e[cnt].to = v;17 e[cnt].nxt = head[u];18 head[u] = cnt;19 }20 21 void dfs(int u,int c)22 {23 vis[u] = true;24 if (c==1) col[u]=2, ans2++;25 else if (c==2) col[u] = 1, ans1++;26 for (int i=head[u]; i; i=e[i].nxt)27 {28 int v = e[i].to;29 if (vis[v]) //不能写成if(vis[i]&&col[u]==col[v]),影响到else的执行 30 {31 if (col[v]==col[u])32 flag = false;33 }34 else dfs(v,col[u]);35 }36 }37 int main()38 {39 scanf("%d%d",&n,&m);40 for (int x,y,i=1; i<=m; ++i)41 {42 scanf("%d%d",&x,&y);43 add(x,y);44 add(y,x);45 }46 for (int i=1; i<=n; ++i)47 if (!vis[i])48 {49 ans1 = ans2 = 0;50 dfs(i,1);51 if (flag) ans += min(ans1,ans2);52 else break;53 }54 if (flag) printf("%d",ans);55 else printf("Impossible");56 return 0;57 }
P1330 封锁阳光大学(染色问题)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。