【推導】【貪心】XVII Open Cup named after E.V. Pankratiev Stage 4: Grand Prix of SPb, Sunday, Octorber 9, 2016 Problem H. Path or Coloring
阿新 • • 發佈:2017-09-28
sin pat clas cst 發現 can -- cnblogs ret
題意:給你一張簡單無向圖(但可能不連通),再給你一個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; }
【推導】【貪心】XVII Open Cup named after E.V. Pankratiev Stage 4: Grand Prix of SPb, Sunday, Octorber 9, 2016 Problem H. Path or Coloring