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)/~