题意:有一个无向图和三种颜色,顶点数目n<=500,记从一个顶点u出发所能到的所有顶点的集合为S(u),S(u)中的点可以相互到达且只经过S(u)中的点(不包括u),规定一条边的两个端点不能染相同的颜色,问是否存在一种可行方案。
思路:如果直接暴力的话时间复杂度是3^n,显然无法承受。
考虑任意一个结点u,那么S(u)中的所有点组成的子图是联通的并且S(u)中的点只能染另外两种颜色,由于这个图是联通的,所以染色方案肯定是唯一的,也就是说我们对于每个节点进行一次二分图染色,如果有冲突那么不存在方案。这样一来时间复杂度降为了O(n*n)。
#include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<queue> #include<stack> #include<string> #include<map> #include<set> #include<ctime> #define eps 1e-6 #define LL long long #define pii (pair<int, int>) //#pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const int maxn = 600; const int INF = 500000; vector<int> G[maxn]; char mayor[10] = {0, 'R', 'G', 'B'}; int n, m; int color[maxn]; queue<int> q; bool vis[maxn], vis2[maxn]; bool in[maxn]; bool dfs(int cur, int root) { int sz = G[cur].size(); for(int i = 0; i < sz; i++) { int u = G[cur][i]; if(in[u]) { if(color[u]&&color[cur]!=6-color[root]-color[u]) return false; if(!vis2[u]) { if(!color[u]) color[u] = 6 - color[cur] - color[root]; vis2[u] = 1; if(!dfs(u, root)) return false; } } } return true; } int main() { freopen("mayors.in", "r", stdin); freopen("mayors.out", "w", stdout); //freopen("input.txt", "r", stdin); while(cin >> n >> m) { for(int i = 0; i < m; i++) { int u, v; scanf("%d%d", &u, &v); G[u].push_back(v); G[v].push_back(u); } bool tag = 1; int pos = 1; while(!q.empty() || pos<= n) { if(q.empty()) { for(; pos<= n; pos++) { if(!vis[pos]) { q.push(pos); color[pos] = 1; vis[pos] = 1; break; } } } if(q.empty()) break; int u = q.front(); q.pop(); if(!G[u].size()) continue; //cout << u << endl; memset(in, 0, sizeof(in)); memset(vis2, 0, sizeof(vis2)); int start = G[u][0]; for(int i = 0; i < G[u].size(); i++) { int v = G[u][i]; if(!vis[v]) { q.push(v); vis[v] = 1; } if(color[v]) { start = v; } in[v] = 1; } if(!color[start]) color[start] = 2; if(!dfs(start, u)) { puts("Plan failed"); tag = 0; break; } } if(tag) { puts("Plan OK"); for(int i = 1; i <= n; i++) printf("%c", mayor[color[i]]); puts(""); } } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/u014664226/article/details/48103381