Nowcoder9981C.红和蓝(树形dp)
链接:https://ac.nowcoder.com/acm/contest/9981/C
来源:牛客网
你拿到了一棵树,请你给每个顶点染成红色或蓝色。
要求:每个红点周围有且仅有一个红点,每个蓝点周围有且仅有一个蓝点。
“周围”的定义:某点周围的点指通过邻边直接连接的点。
所谓树,即没有自环、重边和回路的无向连通图。
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+100; int n; vector<int> g[maxn]; //当前节点本身是红色 //说白了就是顶点对 int ans[maxn]; int dep[maxn]; void dfs (int x,int f) { dep[x]=1; int Max=0; for (int y:g[x]) { if (y==f) continue; dfs(y,x); dep[x]+=dep[y]; } } void dfs1 (int x,int f,int c) { int cnt=0,u=-1; ans[x]=c; for (int y:g[x]) { if (y==f) continue; if (dep[y]%2==1) { u=y; cnt++; } } if (cnt!=0&&ans[x]==ans[f]) { printf("-1\n"); exit(0); } if (cnt!=1&&ans[x]!=ans[f]) { printf("-1\n"); exit(0); } if (ans[x]==ans[f]) { for (int y:g[x]) { if (y==f) continue; dfs1(y,x,!c); } } else { dfs1(u,x,c); for (int y:g[x]) { if (y==f||y==u) continue; dfs1(y,x,!c); } } } int main () { scanf("%d",&n); for (int i=1;i<n;i++) { int x,y; scanf("%d%d",&x,&y); g[x].push_back(y); g[y].push_back(x); } dfs(1,0); dfs1(1,0,1); for (int i=1;i<=n;i++) { if (ans[i]==1) printf("R"); else printf("B"); } }