Kruskal重构树
用\(Kruskal\)构建生成树的顺序来构建\(Kruskal\)重构树
两个连通块合并时,新建一个节点,点权为联通这两个连通块边的边权,新节点向两个连通块的根连边,新节点为合并后的连通块的根
得到的树为有\(n\)个叶子节点的二叉树,其满足堆的性质
求一个点\(x\)在只经过边权不大于\(v\)的边所能到达的点。边权从小到大排序,建\(Kruskal\)重构树,得到的是一个大根堆,从\(x\)向上倍增,到达满足点权不大于\(v\)深度最浅的节点,该节点子树中的所有叶子节点\(x\)都可到达
\(code:\)
for(int i=1;i<=m;++i)
{
int x=find(ed[i].x),y=find(ed[i].y);
if(x==y) continue;
val[++tot]=ed[i].v,add(tot,x),add(tot,y);
fa[x]=fa[y]=f[x][0]=f[y][0]=tot;
if(tot==2*n-1) break;
}