Bicoloring |
Here you are asked to solve a simpler similar problem. Youhave to decide whether a given arbitrary connected graph can be bicolored.That is, if one can assign colors (from a palette of two) to the nodes in sucha way that no two adjacent nodes have the same color. To simplify the problemyou can assume:
An input with n = 0 will mark the end of the input and isnot to be processed.
3 3 0 1 1 2 2 0 9 8 0 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0
NOT BICOLORABLE. BICOLORABLE.
题目翻译:
1976年“四色定理”在计算机的帮助下被证明。 这个定理宣告任何一个地图都可以只用四种颜色来填充, 并且没有相邻区域的颜色是相同的。
现在让你解决一个更加简单的问题。 你必须决定给定的任意相连的图能不能够用两种颜色填充。 就是说,如果给其中一个分配一种颜色, 要让所有直接相连的两个节点不能是相同的颜色。 为了让问题更简单,你可以假设:
1. 没有节点是连接向它自己的。
2. 是无向图。 即如果a连接b, 那么b也是连接a的
3. 图是强连接的。就是说至少有一条路径可走向所有节点。
解析:
取第一个点进行染色,如果发现要涂某一块时这个块已经被涂了色,并且与我们要使用的颜色不同的话,就说明这个图不能被染成BICOLORABLE的。
(1)如果没有染色,将它染色,并将它周围的点变成相反色。
(2)如果已经染色,判断是否与现在染色的点的颜色相同,相同,则退出,否则继续。
DFS解法:
#include <iostream> #include <cstdio> #include <string.h> using namespace std; const int N = 210; int edge[N][N]; int vis[N]; int color[N]; int m,n; bool dfs(int u) { for(int i = 0; i < n; i++) { if(edge[u][i]) { if(!vis[i]) { vis[i] = 1; color[i] = !color[u]; dfs(i); } else if(color[i] == color[u]){ return false; } } } return true; } int main() { int u,v; while(scanf("%d",&n) != EOF && n) { scanf("%d",&m); memset(vis,0,sizeof(vis)); memset(edge,0,sizeof(edge)); for(int i = 0; i < m; i++) { scanf("%d%d",&u,&v); edge[u][v] = 1; edge[v][u] = 1; } color[0] = 1; vis[0] = 1; if(dfs(0)) { printf("BICOLORABLE.\n"); }else { printf("NOT BICOLORABLE.\n"); } } return 0; }
#include <iostream> #include <stdio.h> #include <queue> #include <string.h> using namespace std; const int N = 210; int edge[N][N]; int vis[N]; int color[N]; int m,n; bool bfs(int s) { queue<int> q; q.push(s); color[s] = 1; vis[s] = 1; while( !q.empty()) { int front = q.front(); q.pop(); for(int i = 0; i < n; i++) { if(edge[front][i]) { if(!vis[i]) { color[i] = !color[front]; vis[i] = 1; q.push(i); } else if(color[i] == color[front]) { return false; } } } } return true; } int main() { int u,v; while(scanf("%d",&n) != EOF && n) { scanf("%d",&m); memset(edge,0,sizeof(edge)); memset(vis,0,sizeof(vis)); memset(color,0,sizeof(color)); for(int i = 0; i < m; i++) { scanf("%d%d",&u,&v); edge[u][v] = 1; edge[v][u] = 1; } if( bfs(0) ) { printf("BICOLORABLE.\n"); }else { printf("NOT BICOLORABLE.\n"); } } return 0; }