[Lydsy1705月赛]挑战NP-Hard

挑战NP-Hard

题解

看到这道题的问法,感觉很奇怪,为什么要连续两个问呢?最后发现其实两个问是有关系的。

我们可以先暴力对所有的点进行染色,一个点的颜色即为所有相邻节点的mex,这样就可以O\left(n \right )染好色。

如果图上的颜色总数不超过k,那么第一问就有答案了。

否则我们就执行第二问,而图中由第k+1颜色的点到第1颜色的点的路径明显是一条目标路径,点互不相同。而对于颜色为i的点,它相邻点一定有一个颜色为i-1,否则它就是i-1颜色了,我们可以通过这种方式找出路径。

源码

挺好打的

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
using namespace std;
#define MAXN 20005
typedef long long LL; 
int t,n,m,k; 
int head[MAXN],col[MAXN],tot;
int from[MAXN],to[MAXN],nxt[MAXN];
int vis[MAXN],pos;
#define gc() getchar()
template<typename _T>
inline void read(_T &x){
	_T f=1;x=0;char s=gc();
	while(s>'9'||s<'0'){if(s=='-')f=-1;s=gc();}
	while(s>='0'&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=gc();}
	x*=f;
}
void addEdge(int u,int v){
	from[++tot]=u;to[tot]=v;
	nxt[tot]=head[u];head[u]=tot;
}
void dfs(int u){
	++pos;
	for(int i=head[u];i;i=nxt[i])if(col[to[i]])vis[col[to[i]]]=pos;
	for(int i=1;;++i)if(vis[i]<pos){col[u]=i;break;}
	for(int i=head[u];i;i=nxt[i])if(!col[to[i]])dfs(to[i]);
}
void print(int x){
	printf(" %d",x);
	if(col[x]==1)return ;
	for(int i=head[x];i;i=nxt[i])
		if(col[to[i]]==col[x]-1)
			return (void)(print(to[i]));
}
signed main(){
	read(t);
	while(t--){
		memset(head,0,sizeof(head));
		memset(col,0,sizeof(col));
		read(n);read(m);read(k);tot=0;
		for(int i=1;i<=m;i++){
			int u,v;read(u);read(v);
			addEdge(u,v);addEdge(v,u);
		}
		for(int i=1;i<=n;i++)if(!col[i])dfs(i);
		bool flag=true;int id=0;
		for(int i=1;i<=n&&flag;i++)if(col[i]==k+1)id=i,flag=false;
		if(flag){
			printf("color");
			for(int i=1;i<=n;i++)printf(" %d",col[i]);
			puts("");
			continue;
		}
		printf("path");print(id);puts("");
	}
    return 0;
}

谢谢!!!

发布了117 篇原创文章 · 获赞 154 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Tan_tan_tann/article/details/104065027
今日推荐