克魯斯卡爾重構樹總結

作用:通過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);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章