小红的树形 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 ; 
}
全部评论

相关推荐

10-22 15:25
门头沟学院 C++
种花网友小松:求求你别发了,我几乎都快嫉妒得疯了,倒在床上蒙住被子就开始抱着枕头尖叫流泪,嘴里一边喊着卧槽卧槽,一边又忍着,我边发边哭,打字的手都是抖的,后来我的手抖得越来越厉害,从心头涌起的思想、情怀和梦想,这份歆羡和悔恨交织在一起,我的笑还挂在脸上,可是眼泪一下子就掉下来了。求你了别发了,我生活再难再穷我都不会觉得难过,只有你们发这种东西的时候,我的心里像被刀割一样的痛,打着字泪水就忍不住的往下流。
我的求职进度条
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务