红和蓝 题解(思维)
题目链接
题目思路
其实比赛想到了一部分但是自己不知道怎么去实现
直接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;
}
不摆烂了,写题