CF 1083 A. The Fair Nut and the Best Path

房东的猫 提交于 2020-12-13 12:44:08

 

A. The Fair Nut and the Best Path

 

https://codeforces.com/contest/1083/problem/A

题意:

  在一棵树内找一条路径,使得从起点到终点的最后剩下的油最多。(中途没油了不能再走了,可以在每个点加wi升油,减少的油量为路径长度)。

分析:

  dfs一遍可以求出子树内所有点到子树根节点的最大的路径和次大的路径,然后可以直接合并取max,并且和从根节点出发的路径取max。

  两条最大的和次大的合并可能不合法的。从最大的走上来后,不一定可以从根节点在走回去。但是即使不合法的取max是没有影响的,这样的路径一定不是更优的。

代码:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<cmath>
 6 #include<cctype>
 7 #include<set>
 8 #include<queue>
 9 #include<vector>
10 #include<map>
11 using namespace std;
12 typedef long long LL;
13 
14 inline int read() {
15     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
16     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
17 }
18 
19 const int N = 300005;
20 
21 struct Edge{
22     int to, nxt, w;
23     Edge() {}
24     Edge(int a,int b,int c) { to = a, nxt = b, w = c; }
25 }e[N << 1];
26 int head[N], w[N], En;
27 
28 inline void add_edge(int u,int v,int w) {
29     ++En; e[En] = Edge(v, head[u], w); head[u] = En;
30     ++En; e[En] = Edge(u, head[v], w); head[v] = En;
31 }
32 
33 LL f[N], Ans;
34 void dfs(int u,int fa) {
35     f[u] = w[u];
36     LL mx1 = -1e18, mx2 = -1e18;
37     for (int i = head[u]; i; i = e[i].nxt) {
38         int v = e[i].to;
39         if (v == fa) continue;
40         dfs(v, u);
41         LL t = f[v] - e[i].w;
42         if (t > mx1) mx2 = mx1, mx1 = t;
43         else if (t > mx2) mx2 = t;
44         if (f[v] > e[i].w) f[u] = max(f[u], f[v] - e[i].w + w[u]);
45     }
46     Ans = max(Ans, f[u]);
47     Ans = max(Ans, mx1 + mx2 + w[u]);
48 }
49 
50 int main() {
51     int n = read();
52     for (int i = 1; i <= n; ++i) w[i] = read();
53     for (int i = 1; i < n; ++i) {
54         int u = read(), v = read(), w = read();
55         add_edge(u, v, w);
56     }
57     dfs(1, 0);
58     cout << Ans;
59     return 0;
60 }

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!