2021牛客寒假算法基础集训营1 C.红和蓝

  • Post author:
  • Post category:其他



题目链接



题目描述

你拿到了一棵树,请你给每个顶点染成红色或蓝色。

要求:每个红点周围有且仅有一个红点,每个蓝点周围有且仅有一个蓝点。

“周围”的定义:某点周围的点指通过邻边直接连接的点。

所谓树,即没有自环、重边和回路的无向连通图。



输入描述:

第一行一个正整数 n,代表树的顶点个数。(1≤n≤100000)

接下来的n−1行,每行两个正整数u和v,代表点u和点v有一条边连接。 (1≤u,v≤n)

保证输入的一定是一棵合法的树。



输出描述:

如果可以达成染色的要求,请输出一个长度为n的字符串,第i个字符代表第i个顶点的染色情况,‘B’ 代表蓝色,‘R’ 代表红色。(若有多种合法染色的方法,输出任意一种即可)

否则直接输出-1。



输入

4
1 2
2 3
3 4



输出

RRBB



说明

1为红点,它连接的边有只有一个红点:2
2为红点,它连接的边有只有一个红点:1
3为蓝点,它连接的边有只有一个蓝点:4
4为蓝点,它连接的边有只有一个蓝点:3



思路

由于需要将树进行染色,所以我们可以采取DFS遍历树。根据题目要求,每个节点染完色后,其周围应当有且仅有一个节点与其同色。由此可知我们首先需要从叶子节点开始将树上的节点进行分类,在此过程中若出现了两个节点选取同一个父节点(无法满足周围有且仅有一个节点与其同色)或者配对后根节点无法成功配对,则不可能满足条件。而对于可以正确配对的树,我们只需要从根节点向下再次DFS遍历树,将经过的节点染上对应颜色即可。



代码

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
const int maxn=1e6+5;
typedef long long ll;
bool flag;
int n,cnt,tot,col[maxn],pre[maxn],head[maxn];
struct node
{
    int to;
    int next;
}maze[maxn];
void add(int u,int v)
{
    maze[++cnt].next=head[u];
    maze[cnt].to=v;
    head[u]=cnt;
}
void dfs(int x,int fa)
{
    int son=0;
    for(int i=head[x];i;i=maze[i].next)
    {
        int to=maze[i].to;
        if(to==fa)
            continue;
        son++;
        dfs(to,x);
    }
    if(son==0||pre[x]==0)
    {
        if(pre[fa])
        {
            flag=1;
            return ;
        }
        pre[x]=pre[fa]=++tot;
    }
}
void dfs1(int x,int fa)
{
    for(int i=head[x];i;i=maze[i].next)
    {
        int to=maze[i].to;
        if(to==fa)
            continue;
        if(pre[x]==pre[to])
            col[to]=col[x];
        else
            col[to]=col[x]^1;
        dfs1(to,x);
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cin>>n;
    for(int i=1;i<n;i++)
    {
        int u,v;
        cin>>u>>v;
        add(u,v);
        add(v,u);
    }
    col[1]=1;
    dfs(1,0);
    if(flag||pre[0])
    {
        cout<<"-1"<<"\n";
        return 0;
    }
    dfs1(1,0);
    for(int i=1;i<=n;i++)
    {
        if(col[i]==1)
            cout<<"R";
        else
            cout<<"B";
    }
    return 0;
}



版权声明:本文为WTMDNM_原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。