其实就是让你调整一些树边的边权,使得根到每个叶子结点的路径一样长
我们令d[i]为i到根的距离,mg[i]为i的子树中d的最大值,那么显然可以用一次dfs求出,让后做一次dp即可:我们每次将点x的权值加上mg[1]-mg[x]-k,让后递归下去,这相当于一个贪心的过程
#include结果我们发现可以优化,其实答案就是Σmg[f[i]]-mg[i]#include #include #define N 500010using namespace std;struct Edge{ int v,c,nt; } G[N<<1];int h[N],f[N],sz[N],n,m,cnt=0,R; long long A=0,mg[N],d[N];inline void adj(int x,int y,int c){ G[++cnt]=(Edge){y,c,h[x]}; h[x]=cnt; }void dfs(int x,int p){ f[x]=p; sz[x]=1; mg[x]=d[x]; for(int v,i=h[x];i;i=G[i].nt) if((v=G[i].v)!=p) { d[v]=d[x]+G[i].c; dfs(v,x); sz[x]+=sz[v]; mg[x]=max(mg[x],mg[v]); }}void dp(int x,int k){ A+=(R-mg[x])-k; for(int v,i=h[x];i;i=G[i].nt) if((v=G[i].v)!=f[x]) dp(v,(R-mg[x]));}int main(){ scanf("%d",&n); for(int x,y,c,i=1;i
#include#include #include #define N 500010using namespace std;struct Edge{ int v,c,nt; } G[N<<1];int h[N],f[N],sz[N],n,m,cnt=0,R; long long A=0,mg[N],d[N];inline void adj(int x,int y,int c){ G[++cnt]=(Edge){y,c,h[x]}; h[x]=cnt; }void dfs(int x,int p){ f[x]=p; sz[x]=1; mg[x]=d[x]; for(int v,i=h[x];i;i=G[i].nt) if((v=G[i].v)!=p) { d[v]=d[x]+G[i].c; dfs(v,x); sz[x]+=sz[v]; mg[x]=max(mg[x],mg[v]); }}int main(){ scanf("%d",&n); for(int x,y,c,i=1;i