【推导】【贪心】XVII Open Cup named after E.V. Pankratiev Stage 4: Grand Prix of SPb, Sunday, Octorber 9, 2016 Problem H. Path or Coloring

题意:给你一张简单无向图(但可能不连通),再给你一个K,让你求解任意一个问题:K染色或者输出一条K长路径。

直接贪心染色,对一个点染上其相邻的点的颜色集合之中,未出现过的最小的颜色。

如果染成就染成了。如果到某个点,发现染不成,则倒着按照颜色从大到小回去,则一定恰好可以找出一条K长度的路径。

#include<cstdio>
#include<cstring>
using namespace std;
int first[1005],next[20005],v[20005],e,co[1005];
void AddEdge(int U,int V){
	v[++e]=V;
	next[e]=first[U];
	first[U]=e;
}
int T,n,m,K;
bool cant[1005];
bool df2(int U){
	printf(" %d",U);
	if(co[U]==1){
		puts("");
		return 1;
	}
	for(int i=first[U];i;i=next[i]){
		if(co[v[i]]==co[U]-1){
			if(df2(v[i])){
				return 1;
			}
			break;
		}
	}
	return 0;
}
bool dfs(int U){
	int sta;
	for(int i=first[U];i;i=next[i]){
		if(co[v[i]]){
			cant[co[v[i]]]=1;
			if(co[v[i]]==K){
				sta=v[i];
			}
		}
	}
	for(int i=1;i<=K;++i){
		if(!cant[i]){
			co[U]=i;
			break;
		}
	}
	if(!co[U]){
		printf("path %d",U);
		df2(sta);
		return 1;
	}
	for(int i=first[U];i;i=next[i]){
		if(co[v[i]]){
			cant[co[v[i]]]=0;
		}
	}
	for(int i=first[U];i;i=next[i]){
		if(!co[v[i]]){
			if(dfs(v[i])){
				return 1;
			}
		}
	}
	return 0;
}
int main(){
//	freopen("h.in","r",stdin);
	int x,y;
	scanf("%d",&T);
	for(;T;--T){
		e=0;
		memset(first,0,sizeof(first));
		scanf("%d%d%d",&n,&m,&K);
		for(int i=1;i<=m;++i){
			scanf("%d%d",&x,&y);
			AddEdge(x,y);
			AddEdge(y,x);
		}
		memset(co,0,sizeof(co));
		memset(cant,0,sizeof(cant));
		bool sol_path=0;
		for(int i=1;i<=n;++i){
			if(!co[i]){
				if(dfs(i)){
					sol_path=1;
					break;
				}
			}
		}
		if(!sol_path){
			printf("coloring");
			for(int i=1;i<=n;++i){
				printf(" %d",co[i]);
			}
			puts("");
		}
	}
	return 0;
}
posted @ 2017-09-28 18:41  AutSky_JadeK  阅读(247)  评论(0编辑  收藏  举报
TVアニメ「Charlotte(シャーロット)」公式サイト TVアニメ「Charlotte(シャーロット)」公式サイト