题意:有一个无向图和三种颜色,顶点数目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