The Fair Nut and the Best Path CodeForces - 1083A(树形dp)

The Fair Nut is going to travel to the Tree Country, in which there are n cities. Most of the land of this country is covered by forest. Furthermore, the local road system forms a tree (connected graph without cycles). Nut wants to rent a car in the city u and go by a simple path to city v. He hasn’t determined the path, so it’s time to do it. Note that chosen path can consist of only one vertex.

A filling station is located in every city. Because of strange law, Nut can buy only wi liters of gasoline in the i-th city. We can assume, that he has infinite money. Each road has a length, and as soon as Nut drives through this road, the amount of gasoline decreases by length. Of course, Nut can’t choose a path, which consists of roads, where he runs out of gasoline. He can buy gasoline in every visited city, even in the first and the last.

He also wants to find the maximum amount of gasoline that he can have at the end of the path. Help him: count it.

Input
The first line contains a single integer n (1≤n≤3⋅105) — the number of cities.

The second line contains n integers w1,w2,…,wn (0≤wi≤109) — the maximum amounts of liters of gasoline that Nut can buy in cities.

Each of the next n−1 lines describes road and contains three integers u, v, c (1≤u,v≤n, 1≤c≤109, u≠v), where u and v — cities that are connected by this road and c — its length.

It is guaranteed that graph of road connectivity is a tree.

Output
Print one number — the maximum amount of gasoline that he can have at the end of the path.

Examples
Input
3
1 3 3
1 2 2
1 3 2
Output
3
Input
5
6 3 2 5 0
1 2 10
2 3 3
2 4 1
1 5 1
Output
7
Note
The optimal way in the first example is 2→1→3.
在这里插入图片描述

The optimal way in the second example is 2→4.
在这里插入图片描述
思路:说是dp,但是其实更像是一个贪心问题。首先有一点需要明确的是,这路径可以只是一个点,也就是说,起点就是终点。这点明确之后,我们可以想一下,以x为根的子树中,如果说这个子树中存在最大的边,那么有3种情况。
①x本身就是起点和终点。
②x的子树中,价值最大的边+x。
③x的子树中,价值最大的边+x+价值次大的边。
往上面返回的时候,我们应该返回x为根的子树中价值最大,也就是在①或者②中返回最大的一个。为什么不能有③呢?因为这样的话,就会有边重复走不符合题意。
代码如下:

#include<bits/stdc++.h>
#define ll long long
#define inf 1e18
using namespace std;

const int maxx=3e5+100;
struct edge{
	int to,next,w;
}e[maxx<<1];
int head[maxx<<1];
int w[maxx];
int n,tot=0;

inline void init()
{
	tot=0;
	memset(head,-1,sizeof(head));
}
inline void add(int u,int v,int w)
{
	e[tot].to=v,e[tot].next=head[u],e[tot].w=w,head[u]=tot++;
}
inline ll dfs(int u,int f,ll &ans)
{
	ll _max1=-1e18,_max2=-1e18;
	for(int i=head[u];i!=-1;i=e[i].next)
	{
		int to=e[i].to;
		if(to==f) continue;
		ll sum=dfs(to,u,ans)-(ll)e[i].w;
		if(_max1<sum) _max2=_max1,_max1=sum;
		else _max2=max(_max2,sum);
	}
	ans=max(ans,(ll)w[u]);
	if(_max1==-1e18) return (ll)w[u];
	else 
	{
		ans=max(_max1+(ll)w[u],ans);
		ans=max(_max1+_max2+(ll)w[u],ans);
		if(_max1+(ll)w[u]<=(ll)w[u]) return (ll)w[u];
		else return _max1+(ll)w[u];
	}
}
int main()
{
	scanf("%d",&n);
	init();
	for(int i=1;i<=n;i++) scanf("%d",&w[i]);
	int x,y,ww;
	for(int i=1;i<n;i++)
	{
		scanf("%d%d%d",&x,&y,&ww);
		add(x,y,ww);
		add(y,x,ww);
	}
	ll ans=-1e18;
	dfs(1,0,ans);
	cout<<ans<<endl;
	return 0;
}

努力加油a啊,(o)/~

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

starlet_kiss

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值