Enlace del tema: haga clic aquí ~
Tema
- Tienes un árbol, por favor tiñe cada vértice de rojo o azul.
- Requisitos: Hay un solo punto rojo alrededor de cada punto rojo, y solo un punto azul alrededor de cada punto azul.
- Finalmente, imprima el color de cada punto, R / B, si no es posible, salida -1
- Rango 1≤n≤100000
Ideas
- Solo hay un rojo a2 en el lado del rojo a1, por lo que solo hay un rojo a1 en el lado del rojo a2. Los dos se pueden unir a un punto. El punto azul es el mismo, por lo que el número de puntos debe ser incluso.
- Luego, el problema se convierte en un color de gráfico bipartito, solo hay dos colores y los colores adyacentes son diferentes. Luego, puede vincular desde el nodo hoja, porque cada nodo hoja tiene sólo un padre. Si el padre ha sido vinculado, entonces no existe tal gráfico.
- Después de unir a un punto, se puede teñir con dfs.
código 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;
}