传送门
考试的时候完全想不出来。
考虑尝试对图进行贪心染色,col[x]=mex(col[y]),其中x与y有边,且y已被染过色
若max(col[i])<=k,那么k染色问题就解决了
否则随便选一个颜色是k+1的点,按照颜色递减走,一定可以走出一条边数为k的简单路径
因为如果一个点col是x,在x!=1是,必然有一个与其相邻的点y满足col[y]=x-1(否则这个点的col值就可以取到x-1)了。
时间复杂度O(n+m)
#include<map>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 1010
#define M 20202
using namespace std;
int T,tot,n,m,k,x,y,fl,pos;
int head[N],vis[N],col[N];
struct edge{int to,next;}e[M];
void add(int x,int y){
e[++tot]=(edge){y,head[x]};
head[x]=tot;
}
void dfs(int x){
pos++;
for (int i=head[x];i;i=e[i].next)
if (col[e[i].to])
vis[col[e[i].to]]=pos;
for (int i=1;;i++)
if (vis[i]<pos){
col[x]=i; break;
}
for (int i=head[x];i;i=e[i].next)
if (!col[e[i].to])
dfs(e[i].to);
}
void solve(){
scanf("%d%d%d",&n,&m,&k);
tot=0;
for (int i=1;i<=n;i++) head[i]=col[i]=0;
for (int i=1;i<=m;i++){
scanf("%d%d",&x,&y);
add(x,y); add(y,x);
}
for (int i=1;i<=n;i++)
if (!col[i]) dfs(i);
fl=1;
for (int i=1;i<=n&&fl;i++)
if (col[i]>k) fl=0;
if (fl){
printf("color");
for (int i=1;i<=n;i++) printf(" %d",col[i]);
puts("");
return;
}
for (int i=1;i<=n;i++)
if (col[i]==k+1){
x=i; break;
}
printf("path");
for (int i=1;i<=k+1;i++){
printf(" %d",x);
for (int j=head[x];j;j=e[j].next)
if (col[e[j].to]==col[x]-1){
x=e[j].to; break;
}
}
puts("");
}
int main(){
scanf("%d",&T);
while (T--) solve();
}