题目链接:点这里~
题目大意
- 你拿到了一棵树,请你给每个顶点染成红色或蓝色。
- 要求:每个红点周围有且仅有一个红点,每个蓝点周围有且仅有一个蓝点。
- 最后输出每个点的颜色,R/B,如果不可以输出-1
- 范围1≤n≤100000
思路
- 红a1边上只有一个红a2,那么红a2边上也只有一个红a1,两者可以绑定到成一个点,蓝点同理,所以点数一定是偶数。
- 那么问题就转换成二分图染色,只有两种颜色,相邻的颜色不同。那么可以从叶节点往上绑定,因为每个叶节点只有一个父亲,如果这个父亲已经绑定过了,那么就不存在这样的图了。
- 绑定成一个点之后呢,就可以dfs染色了。
ac代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 1e5 + 5;
int vis[maxn], id[maxn], pre[maxn], col[maxn];
//vis表示节点是否绑定过,id表示节点绑定的编号,pre表示父节点编号,col表示节点颜色
int flag = 0;
vector<int> v[maxn];
void dfs1(int s, int fa){
for(auto it : v[s]){
if(it == fa) continue;
pre[it] = s;
dfs1(it, s);
if(flag) return;
}
//自下而上绑定
if(!vis[s]){
if(vis[pre[s]]){ //如果父亲已经绑定过了,那么节点s就成孤儿了,所以不行
flag = 1;
return;
}
vis[s] = vis[pre[s]] = 1;
id[s] = id[pre[s]] = s; //绑定成节点s
}
}
void dfs2(int s, int fa, int color){
col[s] = color; //染色
for(auto it : v[s]){
if(it == fa) continue;
if(id[s] == id[it]) dfs2(it, s, color); //绑定同一节点,颜色一样
else dfs2(it, s, 1 ^ color); //否则是二分图上相邻节点,颜色不同
}
}
int main(){
int n; cin >> n;
for(int i = 1; i < n; i ++){
int x, y;
cin >> x >> y;
v[x].push_back(y);
v[y].push_back(x);
}
if(n & 1){ //奇数不行
puts("-1");
return 0;
}
dfs1(1, 0); //绑定节点
if(flag == 1){ //绑定失败
puts("-1");
return 0;
}
dfs2(1, 0, 1);//染色
for(int i = 1; i <= n; i ++){
if(col[i]) printf("R");
else printf("B");
}
cout << endl;
return 0;
}