题意:给你一张简单无向图(但可能不连通),再给你一个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; }
时间: 2024-10-15 00:58:25