NC233245. 筑巢
描述
小沙转生成为了蚂蚁子,现在他攻占了一颗树,树里面还是实心的木头,所以小沙想要将里面连续的一部分掏空让自己居住(因为小沙只想住一个家)。但是并不是每个部分都适合开采,某些地方的开采后可能导致舒适度下降。
将上面的问题抽象出来,我们可以理解成,给定你一个n个节点的树,你需要在树上选取一个非空连通块,使其舒适度和最大。选择的边和点的舒适度都是舒适度。
输入描述
第一行输入一个正整数数
第二行输入n个数 每个数代表该节点开采后的舒适度
随后n-1行每行输入3个数x,y,w分别代表x与y之间有一条舒适度为w的路
输出描述
输出小沙的家的最大舒适度
示例1
输入:
5 1 2 3 4 5 1 2 -3 1 3 3 1 4 -5 1 5 -2
输出:
10
Python3 解法, 执行用时: 1268ms, 内存消耗: 49220K, 提交时间: 2022-03-22 13:58:25
n=int(input()) a=[[] for i in range(n+1)] dp=[-10**18 for i in range(n+1)] v=list(map(int,input().split())) for i in range(n-1): x,y,w=map(int,input().split()) x-=1 y-=1 a[x].append([y,w]) a[y].append([x,w]) # print(x,y) global res res=-10**18 def dfs(u,fa): dp[u] = v[u] global res for j,w in a[u]: if j==fa: continue dfs(j,u) dp[u] += max(0,dp[j] + w) res=max(res,dp[u]) dfs(0,-1) print(res)
C++(clang++ 11.0.1) 解法, 执行用时: 203ms, 内存消耗: 8304K, 提交时间: 2023-08-13 15:16:04
#include<bits/stdc++.h> using namespace std; const int MAXN = 1e5+7; int n; vector<pair<int, int>> G[MAXN]; int64_t A[MAXN]; void dfs(int s, int f) { for (auto [t, w]: G[s]) if (t != f) dfs(t, s), A[s]+=max(0l, A[t]+w); } int main(){ cin >> n; for (int i = 1; i <= n; i++) cin >> A[i]; for (int i = 1, u, v, w; i < n; i++) cin >> u >> v >> w, G[u].push_back({v, w}), G[v].push_back({u, w}); dfs(1, 0); cout << *max_element(A+1, A+n+1) << endl; }