挑战NP-Hard
题解
看到这道题的问法,感觉很奇怪,为什么要连续两个问呢?最后发现其实两个问是有关系的。
我们可以先暴力对所有的点进行染色,一个点的颜色即为所有相邻节点的mex,这样就可以染好色。
如果图上的颜色总数不超过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;
}