我们设 cost(y,x) c o s t ( y , x ) 表示从 y y 刷到 x x 的代价,设 du=h−depth(u), d u = h − d e p t h ( u ) , 。
代码:
#include
#define N 200010
#define ll long long
#define its set::iterator
#define rits set::reverse_iterator
using namespace std;
int n,tote,mxd,con[N],nxt[N<<1],to[N<<1],d[N],sz[N],id[N];
ll C[N],H[N],f[N],lazy[N];
struct node
{
ll c,h;
friend bool operator <(const node a,const node b)
{
if(a.c==b.c) return a.h>b.h;
return a.c>b.c;
}
};
set s[N];
bool chkmin(ll &a,ll b)
{
return (a<=b?0:(a=b,1));
}
ll cal(node a,ll x)
{
return a.c*x*x+(a.c+a.c*a.c*2)*x+a.h;
}
double inter(node a,node b)
{
double A=a.c-b.c,B=a.c-b.c+(a.c*a.c-b.c*b.c)*2,C=a.h-b.h;
return (sqrt(B*B-A*C*4)*(A>0?1:-1)-B)/(A*2);
}
void adde(int x,int y)
{
to[++tote]=y;
nxt[tote]=con[x];
con[x]=tote;
}
its pre(its x)
{
its t=x;t--;
return t;
}
its suc(its x)
{
its t=x;t++;
return t;
}
bool check(node a,node b)
{
if(a.c<=b.c&&a.h<=b.h) return 1;
return 0;
}
void dfs0(int v,int fa)
{
mxd=max(d[v],mxd);
sz[v]=1;
for(int p=con[v];p;p=nxt[p])
if(to[p]!=fa)
d[to[p]]=d[v]+1,dfs0(to[p],v),sz[v]+=sz[to[p]];
}
void ins(set &a,node p)
{
its t0=a.insert(p).first;
if(t0!=a.begin()&&suc(t0)!=a.end())
if(check(*suc(t0),*t0)||inter(*suc(t0),*t0)<=inter(*t0,*pre(t0))) {a.erase(t0);return ;}
if(t0!=a.begin())
while(pre(t0)!=a.begin())
if(check(*t0,*pre(t0))||inter(*t0,*pre(t0))<=inter(*pre(t0),*pre(pre(t0)))) a.erase(pre(t0));
else break;
if(suc(t0)!=a.end())
while(suc(suc(t0))!=a.end())
if(inter(*suc(suc(t0)),*suc(t0))<=inter(*suc(t0),*t0)) a.erase(suc(t0));
else break;
}
void dp(int v,int fa)
{
ll tot=0,hs=0;
for(int p=con[v];p;p=nxt[p])
if(to[p]!=fa)
{
dp(to[p],v),tot+=f[to[p]];
if(sz[to[p]]>sz[hs]) hs=to[p];
}
for(int p=con[v];p;p=nxt[p])
if(to[p]!=fa)
{
its t;
lazy[id[to[p]]]+=tot-f[to[p]];
for(t=s[id[to[p]]].begin();suc(t)!=s[id[to[p]]].end();)
if(inter(*suc(t),*t)>d[v]) break;
else s[id[to[p]]].erase(t++);
chkmin(f[v],cal(*t,d[v])+lazy[id[to[p]]]);
}
if(!hs) id[v]=v;
else
{
id[v]=id[hs];
for(int p=con[v];p;p=nxt[p])
if(to[p]!=fa&&to[p]!=hs)
for(its t=s[id[to[p]]].begin();t!=s[id[to[p]]].end();t++)
{
node x=(*t);
x.h+=lazy[id[to[p]]]-lazy[id[v]];
ins(s[id[v]],x);
}
}
node x;
x.c=C[v];
x.h=2ll*(-H[v]+C[v]*C[v]*(1ll-d[v])-C[v]*(d[v]-1ll)*d[v]/2ll);
chkmin(f[v],cal(x,d[v])+tot);
x.h+=tot-lazy[id[v]];
ins(s[id[v]],x);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld%lld",&H[i],&C[i]);
for(int i=1;iint x,y;
scanf("%d%d",&x,&y);
adde(x,y);adde(y,x);
}
memset(f,0x3f,sizeof(f));
dfs0(1,0);
for(int i=1;i<=n;i++)
d[i]=mxd-d[i];
dp(1,0);
printf("%lld",f[1]>>1);
return 0;
}