银河英雄传说

题目链接

题意:给你n个战舰,第i个战舰初始都在第i列上,现在有两种操作:M i j,把i列的战舰按原有顺序依次接到j列尾端,C i j,查询i与j号战舰之间隔几个战舰,

如果未在一列输出-1。

思路:把并查集稍微改一下就行了,用一个数组记录隔几个,还用一个数组记录每一列的当前容量。

#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<cstdio>
#include<cmath>
#define ll long long
using namespace std;
int fa[30010],num[30010],dis[30010];
int get(int x)
{ 
    if(x!=fa[x])
    {
        int k=fa[x];
        fa[x]=get(fa[x]);
        dis[x]+=dis[k];
        num[x]=num[fa[x]];
    }
    return fa[x]; 
}
void merge(int x,int y)
{
    int r1=get(x),r2=get(y);
    if(r1!=r2)
    {
        fa[r1]=r2;
        dis[r1]=dis[r2]+num[r2];
        num[r2]+=num[r1];
        num[r1]=num[r2];
    }
}
int query(int x,int y)
{
    int r1=get(x),r2=get(y);
    if(r1!=r2)
    return -1;
    else
    return abs(dis[x]-dis[y])-1;
}
int main()
{
    int t;
    for(int i=1;i<=30008;i++)
    {
        fa[i]=i;
        num[i]=1;
    }
    scanf("%d",&t);
    while(t--)
    {
        char c[2];
        int x,y;
        scanf("%s",c);
    //    getchar();
        scanf("%d%d",&x,&y);
        //printf("%c\n",c);
        if(c[0]=='M')
        merge(x,y);
        else
        {
            printf("%d\n",query(x,y));
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/2462478392Lee/p/11343655.html