列表

详情


NC202475. 树上子链

描述

给定一棵树 T ,树 T 上每个点都有一个权值。
定义一颗树的子链的大小为:这个子链上所有结点的权值和 。
请在树 T 中找出一条最大的子链并输出。

输入描述

第一行输入一个
接下来一行包含n个数,对于每个数 ,表示 i 结点的权值。
接下来有n-1行,每一行包含两个数u,v(  , u != v),表示u与v之间有一条边。

输出描述

仅包含一个数,表示我们所需要的答案。

示例1

输入:

5
2 -1 -1 -2 3
1 2
2 3
2 4
2 5

输出:

4

说明:

样例中最大子链为1 -> 2 -> 5

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

Python3 解法, 执行用时: 766ms, 内存消耗: 120848K, 提交时间: 2022-07-15 13:17:10

import sys
sys.setrecursionlimit(200000)
n = int(input())
val = [0] + list(map(int, input().split()))
g = [[] for _ in range(n + 1)]
s = [0] * (n + 1)
for _ in range(n - 1):
    a, b = map(int, input().split())
    g[a].append(b)
    g[b].append(a)

ans=-10**18
def dfs1(u, fa):
    global ans
    s[u] = val[u]
    for v in g[u]:
        if v == fa: continue
        dfs1(v, u)
        ans = max(ans, s[u] + s[v])
        s[u]=max(s[u],val[u]+s[v])
    ans=max(ans,s[u])
dfs1(1,0)
print(ans)

C++(clang++ 11.0.1) 解法, 执行用时: 122ms, 内存消耗: 12148K, 提交时间: 2023-05-22 18:41:07

#include<bits/stdc++.h>
#define N 100005
using namespace std;
long long n,a[N],f[N],maxi=-1e18;
vector<vector<int>> e(N);
void dfs(int u,int fa){
	f[u]=a[u];
    maxi=max(maxi,f[u]);
	for(auto v:e[u]){
		if(v==fa) continue;
		dfs(v,u);
		maxi=max(maxi,f[u]+f[v]);
		f[u]=max(f[u],f[v]+a[u]);
	}
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<n;i++){
		int x,y;
		cin>>x>>y;
		e[x].push_back(y);
		e[y].push_back(x);
	}
	dfs(1,0);
    cout<<maxi;
}

上一题