Luogu P1196 [NOI2002]银河英雄传说

带权并查集

对于每一列记录id[i]表示第i号战舰的序号,sum[i]表示第i号战舰所在列的战舰个数

对于每一个合并操作,无法对每一个所在当前列的战舰信息进行更新

所以只对队头战舰的信息进行修改,用类似线段树中懒标记的方法

当要对这一艘战舰进行访问时,对其信息进行修改

注意,在并查集中先要对其列首战舰进行更新,在对当前战舰更新

#include <bits/stdc++.h>
using namespace std;
const int MAXN=31000;
int t,fa[MAXN],id[MAXN],sum[MAXN];
inline int find(int x)
{
    if (fa[x]==x)
      return fa[x];
    int f;
    f=fa[x];
    fa[x]=find(fa[x]);//注意
    id[x]+=id[f];//在父亲更新后更新当前
    return fa[x];
}
int main()
{
    scanf("%d",&t);
    for (int i=1;i<=30010;i++)//初始化
    {
        sum[i]=1;
        fa[i]=i;
        id[i]=0;
    }
    for (int i=1;i<=t;i++)
    {
        char ch[10];
        int a,b;
        scanf("%s%d%d",ch,&a,&b);
        if (ch[0]=='M')
        {
            if (find(a)!=find(b))
            {
                int ga,gb;
                ga=find(a);
                gb=find(b);
                id[ga]+=sum[gb];
                sum[gb]+=sum[ga];
                sum[ga]=0;
                fa[ga]=gb;
            }
        }
        else
        {
            if (find(a)!=find(b))
              printf("-1\n");
            else
              printf("%d\n",abs(id[b]-id[a])-1);
        }
    }
}

 

posted @ 2019-07-19 21:45  SevenDawns  阅读(179)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end