[Nowcoder 217042] CCAサブツリー

CCAサブツリー

タイトルリンク:nowcoder 217042

Niu Keへ:

->クリックしてジャンプ<->

一般的なアイデア

ドットの重みを持つツリーがあり、ルートノードは11です。1
2つのポイントを選択する必要があります。それらは他のポイントの祖先ではなく、サブツリーの重みの合計を最大化する必要があります。
2点選択できない場合は出力してくださいError

アイデア

この質問はツリーDPである必要があると考えることができます。

最初に特定のポイントからのサブツリーDPのポイントの重みとqiq_iを検討しますq、そしてあなたはそのような方法を使うことを考えることができます。
私たちは、DPのある時点のサブツリー内の各点持ってXXをxqxq_xqX最大値big_ soni big \ _son_ib i g _ s o n
次に、選択した2つのポイントの最も近い共通の祖先を列挙することを検討し、そのサブツリーのbig _ son big \ _sonを配置します。b i g _ s o nの2つの最大値を加算して、このポイントが最も近い共通の祖先である場合に回答が持つことができる最大値取得します。

次に、それらすべてを最大値にすることができます。それだけです。

コード

#include<cstdio>
#include<iostream>
#define ll long long

using namespace std;

struct node {
    
    
	int to, nxt;
}e[400001];
int n, a[200001], x, y;
int KK, le[200001], maxn_dep;
ll ans, big_son[200001], sum[200001];

void add(int x, int y) {
    
    
	e[++KK] = (node){
    
    y, le[x]}; le[x] = KK; 
}

void dfs(int now, int father, int dep) {
    
    
	maxn_dep = max(maxn_dep, dep);
	big_son[now] = -0x3f3f3f3f3f3f3f3f;
	sum[now] = a[now];
	
	ll maxn = -0x3f3f3f3f3f3f3f3f, maxn2 = -0x3f3f3f3f3f3f3f3f;
	for (int i = le[now]; i; i = e[i].nxt)
		if (e[i].to != father) {
    
    
			dfs(e[i].to, now, dep + 1);
			big_son[now] = max(big_son[now], big_son[e[i].to]);
			sum[now] += sum[e[i].to];
			
			if (big_son[e[i].to] > maxn) {
    
    
				maxn2 = maxn;
				maxn = big_son[e[i].to];
			}
			else if (big_son[e[i].to] > maxn2) maxn2 = big_son[e[i].to];
		}
	
	big_son[now] = max(big_son[now], sum[now]);
	
	ans = max(ans, maxn + maxn2);
}

int main() {
    
    
	ans = -0x3f3f3f3f3f3f3f3f; 
	
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
	
	for (int i = 1; i < n; i++) {
    
    
		scanf("%d %d", &x, &y);
		add(x, y);
		add(y, x);
	}
	
	dfs(1, 0, 1);
	
	if (maxn_dep == n) printf("Error");
		else printf("%lld", ans);
	
	return 0;
}

おすすめ

転載: blog.csdn.net/weixin_43346722/article/details/115219563