题目
题解思路
手模几次,可以发现,非叶子节点只能连接一个叶子节点。
因为叶子节点必须和父节点的颜色相同。
其次树必须满足每个节点必须有且只有1个相同颜色的节点。
之前一直不清楚如何处理无根树,现在懂了一点,无根树的任意一个点都可以拿来当场根节点来使用(手模后依然符合树的定义)。
这样我们似乎,只需让每个节点只匹配一个相同颜色的节点,并且叶子节点必须和父节点匹配。
这样我们利用后序遍历,先到叶子节点的父节点,将父节点和叶子节点相连。后续往上返回的时候,让两个相连的节点并且没有被匹配的节点颜色相同。
当所有节点都能够匹配到相同颜色的节点的时候。
就是有解。
将根节点染色。
然后我们利用可以前序遍历,将相同匹配的颜色颜色相同,不同匹配的则用不同颜色。
以前碰到这种问题一直不知道怎么更好处理。
现在是学到了。
AC代码
#include <bits/stdc++.h>
//#include <unordered_map>
//priority_queue
#define PII pair<int,int>
#define ll long long
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 100010 ;
vector <int> head[N] ;
int vis[N] ;
int s[N] ;
void dfs1(int r , int fa )
{
for ( auto i : head[r] )
{
if ( i == fa )//重边即连回父节点的边
continue ;
dfs1(i,r) ;
if (!vis[i]&&!vis[r])
{
vis[i] = r ;
vis[r] = i ;
}
}
}
void dfs2(int r , int fa )
{
for ( auto i : head[r] )
{
if ( i == fa )
continue ;
if ( vis[i] == r )
{
s[i] = s[r] ;
}else
s[i] = s[r]^1 ;
dfs2(i,r) ;
}
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int n ;
cin >> n ;
for (int i = 1 ; i < n ; i++ )
{
int t1 , t2 ;
cin >> t1 >> t2 ;
head[t1].push_back(t2) ;
head[t2].push_back(t1) ;
}
dfs1(1,0);
int falg = 1 ;
for (int i = 1 ; i <= n ; i++ )
{
if (!vis[i])
falg = 0 ;
}
if (falg)
{
s[1] = 1 ;
dfs2(1,0);
for (int i = 1 ; i <= n ; i++ )
if (s[i] == 1 )
cout << "B";
else
cout << "R";
cout << "\n" ;
}else
{
cout << "-1\n" ;
}
return 0 ;
}