手模几次,可以发现,非叶子节点只能连接一个叶子节点。
因为叶子节点必须和父节点的颜色相同。
其次树必须满足每个节点必须有且只有1个相同颜色的节点。
之前一直不清楚如何处理无根树,现在懂了一点,无根树的任意一个点都可以拿来当场根节点来使用(手模后依然符合树的定义)。
这样我们似乎,只需让每个节点只匹配一个相同颜色的节点,并且叶子节点必须和父节点匹配。
这样我们利用后序遍历,先到叶子节点的父节点,将父节点和叶子节点相连。后续往上返回的时候,让两个相连的节点并且没有被匹配的节点颜色相同。
当所有节点都能够匹配到相同颜色的节点的时候。
就是有解。
将根节点染色。
然后我们利用可以前序遍历,将相同匹配的颜色颜色相同,不同匹配的则用不同颜色。
以前碰到这种问题一直不知道怎么更好处理。
现在是学到了。
#include//#include //priority_queue #define PII pair #define ll long long using namespace std; const int INF = 0x3f3f3f3f; const int N = 100010 ; vector 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 << "-1n" ; } return 0 ; }



