首先根节点的长度为0
我们观察,如果当前子树根节点长度为x,那么他的子树内节点长度不小于
如果只有一个儿子,那么这个儿子编码和父亲编码是一样的
如果有两个儿子,那么这两个儿子分别+1和+0
显然这是一个贪心问题,考虑对于x节点如何贪心
我们把它所有的儿子扒出来,然后按照
那么对于每个节点都这个做一遍就好了
时间复杂度O(N∗log2N)
#include<bits/stdc++.h>
#define sp new int[cnt<<1]
const int N=100010;
using namespace std;
int to[N],nxt[N],sz,fir[N],size[N],n,S,tot;
long long ans;
void add(int x,int y){
nxt[++sz]=fir[x],fir[x]=sz,to[sz]=y;
}
#define add2(x,y) tnxt[++tsz]=tfir[x],tfir[x]=tsz,tto[tsz]=y;
void dfs1(int x){
size[x]=1;
for(int u=fir[x];u;u=nxt[u]){
dfs1(to[u]);
size[x]+=size[to[u]];
}
}
struct node{
int x,v;
bool operator<(const node&a)const{
return v>a.v;
}
};
void dfs(int x,int*dfn,int*l,int dep,int*tfir,int*tnxt,int*tto){
if(x<=S){
dfn[++tot]=x;l[tot]=dep;return;
}
for(int u=tfir[x];u;u=tnxt[u]){
dfs(tto[u],dfn,l,dep+1,tfir,tnxt,tto);
}
}
void dfs2(int x,int len){
ans+=len;
priority_queue<node>q;
int cnt=0;
for(int u=fir[x];u;u=nxt[u]){
cnt++;q.push((node){cnt,size[to[u]]});
}
if(!cnt)return;S=cnt;
int *tfir=sp,tsz=0,*tnxt=sp,*tto=sp,*who=sp,*dfn=sp,*l=sp;
for(int i=0;i<cnt<<1;i++)tfir[i]=tnxt[i]=tto[i]=who[i]=dfn[i]=l[i]=0;
cnt=0;
for(int u=fir[x];u;u=nxt[u]){
cnt++;who[cnt]=to[u];
}
while(q.size()>1){
node a=q.top();q.pop();
node b=q.top();q.pop();
++cnt;add2(cnt,a.x);add2(cnt,b.x);
q.push((node){cnt,a.v+b.v});
}
tot=0;
dfs(cnt,dfn,l,0,tfir,tnxt,tto);
for(int i=1;i<=(cnt+1)>>1;i++)dfs2(who[dfn[i]],len+l[i]);
}
int main(){
scanf("%d\n",&n);
for(int i=2;i<=n;i++){
int x;scanf("%d",&x);add(x,i);
}
dfs1(1);
dfs2(1,0);
cout<<ans<<endl;
}