正题
题目大意
一棵树,可以增长边权长度,要求根节点要每个叶子节点路径长度相等,求最少增加次数。
解题思路
肯定优先修改上面的边,因为这样可以影响最多的点,那么对于每个节点我们都要使它到每个它子树中叶子节点的长度相等就好了。直接树形 d p dp dp。
c o d e code code
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=500010;
struct node{
ll to,w,next;
}a[N*2];
ll ls[N],tot,last[N],f[N],s,n;
void addl(ll x,ll y,ll w)
{
a[++tot].to=y;
a[tot].w=w;
a[tot].next=ls[x];
ls[x]=tot;
}
void dp(ll x,ll fa,ll w)
{
last[x]=w;
for(ll i=ls[x];i;i=a[i].next){
ll y=a[i].to;
if(y==fa) continue;
dp(y,x,w+a[i].w);
last[x]=max(last[y],last[x]);
}
for(ll i=ls[x];i;i=a[i].next){
ll y=a[i].to;
if(y==fa) continue;
f[x]+=f[y];
if(last[y]<last[x])
f[x]+=last[x]-last[y];
}
}
int main()
{
scanf("%lld%lld",&n,&s);
for(ll i=1;i<n;i++){
ll x,y,w;
scanf("%lld%lld%lld",&x,&y,&w);
addl(x,y,w);addl(y,x,w);
}
dp(s,0,0);
printf("%lld",f[s]);
}