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
");
        exit(0);
    }
    if (cnt!=1&&ans[x]!=ans[f]) {
        printf("-1
");
        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");
    }
}  
原文地址:https://www.cnblogs.com/zhanglichen/p/14359210.html