Title Description
answer
One kindClearWater Method: max (0, - (right dot - Right side and * 2))
Because it will hang in the middle of the physical value may be smaller, so consider seeking to finish each of them at least a physical value required subtree
From the sub-tree inquire up the answer of the current point
Meike set up sub-tree away from the root down to the required physical value f, go through contributions to the sum
Due to the current point to add -> son this edge, so actually finish the contribution sum '= sum- right side * 2
Desired physical value f '= max (edge weights + f, 2 * right side -sum), in fact, there are two cases where
① current point -> son -> subtree (-> son), it is the worst case (worst case subtree + right side)
② current point -> son -> sub-tree -> son -> current point, the final contribution actually sum- right side * 2, then you need at least max (0, right side * 2-sum) of physical strength
Obviously for point contribution ≥0 in accordance with the needs of small to large to take
Contribution <0 point, the definition of a reduced amount = - Contribution
Well, according to demand - reducing the amount of descending sort can
prove:
Defined difference = demand - the amount of reduction
For the two sons, and reducing the amount of the difference is provided for the first son of a and B, respectively, for the second cd
Assume has been sorted in accordance with the difference, and after ordering the adjacent two sons, then there a≥c
After the exchange will not prove better
Let x go before these two physical sub-tree, to ensure that no negative numbers in the middle and can achieve demand
Then there
Before the exchange:
x≥a+b,x-b≥c+d
After the exchange:
x≥c+d,x-d≥a+b
According to equation
+ Contribution to the root of physical recovery - Meike sub-tree and reduce the amount of residual strength =, which only restore physical strength is variable, so the rest can be found in the less physically smaller answer =
Since the remaining strength before and after the exchange are xbd, so to make x as small as possible (too much could lead to a surplus)
They became proof
max(a+b,b+c+d)≤max(c+d,a+b+d)
Since a + b + d≤max (c + d, a + b + d), and a + b + d≥a + b and b + c + d (a≥c), so that max (a + b, b + c + d) ≤a + b + d≤max (c + d, a + b + d)
Is proved
code
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define min(a,b) (a<b?a:b)
#define max(a,b) (a>b?a:b)
using namespace std;
struct type{
long long f,sum;
} b[100001],c[100001];
int a[200001][3];
int ls[100001];
int w[100001];
long long f[100001];
long long sum[100001];
int n,i,j,k,l,len;
long long ans;
bool cmp(type a,type b)
{
return a.f<b.f;
}
bool Cmp(type a,type b)
{
return a.f-a.sum>b.f-b.sum;
}
void New(int x,int y,int z)
{
++len;
a[len][0]=y;
a[len][1]=ls[x];
a[len][2]=z;
ls[x]=len;
}
void dfs(int Fa,int t)
{
int i,l1=0,l2=0;
long long now=w[t];
sum[t]=w[t];
for (i=ls[t]; i; i=a[i][1])
if (a[i][0]!=Fa)
{
dfs(t,a[i][0]);
sum[t]+=sum[a[i][0]]-a[i][2]-a[i][2];
}
if (!ls[t]) return;
for (i=ls[t]; i; i=a[i][1])
if (a[i][0]!=Fa)
{
if (sum[a[i][0]]-a[i][2]-a[i][2]>=0)
{
++l1;
b[l1].f=max(f[a[i][0]]+a[i][2],-(sum[a[i][0]]-a[i][2]-a[i][2]));
b[l1].sum=sum[a[i][0]]-a[i][2]-a[i][2];
}
else
{
++l2;
c[l2].f=max(f[a[i][0]]+a[i][2],-(sum[a[i][0]]-a[i][2]-a[i][2]));
c[l2].sum=-(sum[a[i][0]]-a[i][2]-a[i][2]);
}
}
if (l1)
{
sort(b+1,b+l1+1,cmp);
fo(i,1,l1)
{
if (now<b[i].f)
{
f[t]+=b[i].f-now;
now=b[i].f;
}
now+=b[i].sum;
}
}
if (l2)
{
sort(c+1,c+l2+1,Cmp);
if (now<(c[1].f-c[1].sum))
{
f[t]+=(c[1].f-c[1].sum)-now;
now=0;
}
else
now-=(c[1].f-c[1].sum);
fo(i,1,l2)
{
if (i>1)
now+=(c[i-1].f-c[i-1].sum)-(c[i].f-c[i].sum);
if (now<c[i].sum)
{
f[t]+=c[i].sum-now;
now=c[i].sum;
}
now-=c[i].sum;
}
}
}
int main()
{
// freopen("a.in","r",stdin);
// freopen("b.out","w",stdout);
freopen("horse.in","r",stdin);
freopen("horse.out","w",stdout);
scanf("%d",&n);
fo(i,1,n)
scanf("%d",&w[i]);
fo(i,2,n)
{
scanf("%d%d%d",&j,&k,&l);
New(j,k,l);
New(k,j,l);
}
dfs(0,1);
printf("%lld\n",f[1]);
fclose(stdin);
fclose(stdout);
return 0;
}