码迷,mamicode.com
首页 > 其他好文 > 详细

GYM 100345E New Mayors(二分图染色)

时间:2015-08-30 12:57:30      阅读:141      评论:0      收藏:0      [点我收藏+]

标签:gym   二分图染色   

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

版权声明:本文为博主原创文章,未经博主允许不得转载。

GYM 100345E New Mayors(二分图染色)

标签:gym   二分图染色   

原文地址:http://blog.csdn.net/u014664226/article/details/48103381

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!