列表

详情


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;
}

上一题