小红的树形 dp (树形dp)

小红的树形 dp

https://ac.nowcoder.com/acm/contest/75766/E

: ) 树形dp写法

#pragma GCC optimize(3)
#pragma GCC optimize("Ofast,no-stack-protector")
#include <bits/stdc++.h>

using namespace std ;

const int N = 1e6 + 10 ;

std::vector<int> edges[N] ; 
int n ;
int dp[N][2] ; // dp[i , 0/1] 表示以 i 为根节点且为'd'/'p' 的树是否满足任意俩个相邻结点字符不同
char color[N] ; 

void dfs1(int v , int f)
{
	if ( color[v] == '?' ) dp[v][0] = dp[v][1] = 1 ; 
	else if ( color[v] == 'd' ) dp[v][0] = 1 ;
	else dp[v][1] = 1 ; 

	for(auto u : edges[v]) {
		if ( u != f ) {
			dfs1(u , v) ;
			if ( color[v] == '?' ) dp[v][0] &= dp[u][1] , dp[v][1] &= dp[u][0] ;
			else if ( color[v] == 'd' ) dp[v][0] &= dp[u][1] ;
			else dp[v][1] &= dp[u][0] ; 
		}
	}
}

void dfs2(int v,int f) {
	for(auto u : edges[v]) {
		if ( u != f ) {
			if ( color[v] == 'd' ) color[u] = 'p' ;
			else color[u] = 'd' ;
			dfs2(u , v) ;
		}
	}
}
void ret() {
	for(int i = 1 ; i <= n ; i++) cout << color[i] ; 
}

int main()
{
	ios::sync_with_stdio(false) ;
	cin.tie(0) ;
	cout.tie(0) ;

	cin >> n >> color + 1 ;

	for(int i = 1 ; i < n ; i++) {
		int u , v ;
		cin >> u >> v ;
		edges[u].push_back(v) ;
		edges[v].push_back(u) ;
	}

	dfs1(1 , 0) ;


	if ( color[1] == '?' ) 
	{
		if ( !dp[1][0] && !dp[1][1] ) cout << -1 << '\n' ;
		else {
			if ( dp[1][0] ) color[1] = 'd' ; else color[1] = 'p' ;
            dfs2(1 , 0)  ;
            ret() ; 
		}
	} 
	else if ( color[1] == 'd' )
    {
        dfs2(1 , 0) ;
        if ( dp[1][0] ) ret() ; else cout << -1 << '\n' ;
    }
	else {
        dfs2(1 , 0) ;
        if ( dp[1][1] ) ret() ; else cout << -1 << '\n' ;
    } 

	return 0 ; 
}
全部评论

相关推荐

qz鹿:*** 祝他毕业就失业
点赞 评论 收藏
分享
10-25 12:05
已编辑
湖南科技大学 Java
若梦难了:我有你这简历,已经大厂乱杀了
点赞 评论 收藏
分享
评论
1
收藏
分享
牛客网
牛客企业服务