您的位置:首页 > 其它

bzoj4878: [Lydsy2017年5月月赛]挑战NP-Hard

2017-05-06 21:47 316 查看
传送门

考试的时候完全想不出来。

考虑尝试对图进行贪心染色,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
,vis
,col
;
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();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: