作用:通过kruskal,我们可以求出两点之间经过边权的最大值最小可以是多少(即瓶颈路)。
如果是点权,则将边权设为两点的最大值。
求出最小生成树后,这个值就是树上路径最值。
但是,有时这样还不够。
我们可以这样建树:连接x,y时,新建点u,权值为边权,并将x,y的所属根的父节点都设为u。
用并查集维护这一过程。
这样,可以得到一棵二叉树,称为克鲁斯卡尔重构树。
此时,x到y的这个值就是树上x,y的lca的点权。
同时,我们可以通过倍增,把从x出发,经过不超过y的边(点)权,能到达的点表示为一棵子树,从而表示为区间。
代码:
int getv(int x) { if(f[x]==x) return x; f[x]=getv(f[x]); return f[x]; } int gettree1(int n,int m,vector<int> ve[400010]) { for(int i=0;i<n;i++) f[i]=i; for(int i=0;i<m;i++) { px[i].x=x[i];px[i].y=y[i]; px[i].z=max(x[i],y[i]); } qsort(px,m,sizeof(SPx),cmp1); for(int i=0,j=n;i<m;i++) { int tx=getv(px[i].x),ty=getv(px[i].y); if(tx==ty) continue; f[tx]=f[ty]=j;f1[tx]=f1[ty]=j; f[j]=j;z1[j]=px[i].z; ve[j].push_back(tx); ve[j++].push_back(ty); } return getv(0); }