红和蓝 题解(思维)

题目链接

题目思路

其实比赛想到了一部分但是自己不知道怎么去实现

直接copy队友的

可以发现,树的叶子节点肯定是与它的父亲节点相匹配的,所以我们深搜一遍,从底层往上去模拟匹配的过程,对于以i为根节点的子树,我们先将它的子子树匹配好,如果 与 i 相邻的儿子节点都有匹配关系,那么说明 i 节点肯定要跟它的父亲节点匹配,如果只剩 1 个点未匹配,那么就让他和 i 节点匹配,如果存在多个,那么肯定不存在解。
最后我们再对根节点任意涂一种颜色,然后根据匹配关系对其他节点依次涂色。

代码

#include<bits/stdc++.h>
#define fi first
#define se second
#define debug cout<<"I AM HERE"<<endl;
using namespace std;
typedef long long ll;
const int maxn=1e5+5,inf=0x3f3f3f3f,mod=1e9+7;
const int eps=1e-6;
int n;
int ans[maxn],match[maxn];
int head[maxn],cnt;
struct edge{
    int to,next;
}e[maxn<<1];
void add(int u,int v){
    e[++cnt]={v,head[u]};
    head[u]=cnt;
}
void dfs1(int son,int fa){
    bool flag=0;
    for(int i=head[son];i;i=e[i].next){
        if(e[i].to==fa) continue;
        dfs1(e[i].to,son);
        if(!match[e[i].to]&&!flag){
            flag=1;
            match[e[i].to]=son;
            match[son]=e[i].to;
        }
    }
}
void dfs2(int son,int fa,int cur){
    ans[son]=cur;
    for(int i=head[son];i;i=e[i].next){
        if(e[i].to==fa) continue;
        if(match[e[i].to]==son){
            dfs2(e[i].to,son,cur);
        }else{
            dfs2(e[i].to,son,-cur);
        }
    }
}
signed main(){
    scanf("%d",&n);
    for(int i=1,u,v;i<=n-1;i++){
        scanf("%d%d",&u,&v);
        add(u,v),add(v,u);
    }
    dfs1(1,1);
    for(int i=1;i<=n;i++){ //有人没匹配上
        if(!match[i]){
            printf("-1\n");
            return 0;
        }
    }
    dfs2(1,1,1);
    for(int i=1;i<=n;i++){
        printf(ans[i]==1?"B":"R");
    }
    return 0;
}

不摆烂了,写题
原文地址:https://www.cnblogs.com/hunxuewangzi/p/14364398.html