边带权并查集--[NOI2002]银河英雄传说

就是维护并查集的时候同时维护每个点到当前fa的距离,find函数加一点就行了。

链接:https://www.luogu.org/problemnew/show/P1196

注意下这里合并时被并的那个并查集的dis要修改为另一个的size

#include<bits/stdc++.h>
using namespace std;
int fa[500010],dis[500010],sz[500010];
int find(int x)
{
    int tmp;
    if(fa[x]==x)return x;
    else
    {
        tmp=find(fa[x]);
        dis[x]+=dis[fa[x]];
        return fa[x]=tmp;
    }
    
}
void merge()
{
    int a,b,tp1,tp2;
    scanf("%d%d",&a,&b);
    tp1=find(a),tp2=find(b);
    if(tp1!=tp2)
    {
        fa[tp1]=tp2;
        dis[tp1]=sz[tp2];
        sz[tp2]+=sz[tp1];
    }
}
void query()
{
    int a,b;
    scanf("%d%d",&a,&b);
    if(find(a)!=find(b))puts("-1");
    else
    {printf("%d\n",abs(dis[a]-dis[b])-1);}
}
int main()
{
    int t;char c;
    for(int i=1;i<=300000;i++)fa[i]=i,dis[i]=0,sz[i]=1;
    scanf("%d",&t);
    for(int i=1;i<=t;i++)
    {
        scanf(" %c",&c);
        if(c=='M')merge();
        else query();
    }
}

猜你喜欢

转载自blog.csdn.net/caoyang1123/article/details/81435048
今日推荐