简单的随机造树方法与树的强度
更多方法可见这篇。
1.随机父亲
树以 \(1\) 为根,则 \(\forall i\in[2,n]\),在 \([1,i)\) 中随机选择一个点作为自身父亲:
namespace RandomTreeGenerator{
mt19937 rnd(time(0));
void generateRandomTree(int n){
int x;for(int i=2;i<=n;++i) x=rnd()%(i-1)+1,Edge(x,i);
}
}
结点个数 \(x(x\le 5\times 10^5)\) 与树的平均深度 \(y\) 的关系,近似 \(y=1.6\log_2 x\):
(对 \(y\) 放大 \(5000\) 倍)可以看出 \(y=\mathcal \Theta(\log x)\)。
2.Prüfer 序列
众所周知,一个长度为 \(n-2\) 的 Prüfer
序列唯一对应着一棵无根树,所以我们可以随机生成一个 Prüfer
序列,将其按模板题的方法转化成树。
namespace RandomTreeGenerator{
mt19937 rnd(time(0));
int d[N],p[N];
void generateRandomTree(int n){
for(int i=1;i<=n;++i) d[i]=1;
for(int i=1;i<=n-2;++i) ++d[p[i]=rnd()%n+1];
int now,pre;for(int i=1;i<=n;++i) if(d[i]==1){pre=now=i;break;}
for(int i=1;i<=n-2;++i){
int f=p[i];Edge(now,f);
if(--d[f]==1&&f<pre) now=f;
else{while(d[++pre]!=1);now=pre;}
}
Edge(now,n);
}
}
结点个数 \(x(x\le 5\times 10^5)\) 与树的平均深度 \(y\) 的关系,近似 \(y=2.5\sqrt x\):
(对 \(y\) 放大 \(100\) 倍)可以看出 \(y=\Theta(\sqrt x)\)。