题解 P1196 【[NOI2002]银河英雄传说】

· · 题解

题意:

//AC代码 :带权并查集

#include<stdio.h>
#include<cmath>
using namespace std;
#define maxn 30005
#define INF 1000000005
#define ll long long
//dis表示i队列的长度,len表示i到根节点的距离
int ff[maxn],dis[maxn],len[maxn];

int find(int x)
{
    if(ff[x]==x)
        return x;
    int t=find(ff[x]);
    len[x]+=len[ff[x]];
    return ff[x]=t;
}

void read(int &x)
{
    x=0;
    bool flag=0;
    char ch=getchar();
    if(ch=='-') flag=1;
    while(ch<'0'||ch>'9')ch=getchar();
    while(ch>='0'&&ch<='9')x*=10,x+=ch-'0',ch=getchar();
    if(flag) x=-x;
}

int main()
{
    int n;
    read(n);
    for(int i=0; i<=maxn; i++)
        ff[i]=i,dis[i]=1;

    for(int i=0; i<n; i++)
    {
        char str;
        scanf(" %c",&str);
        int x,y;
        read(x),read(y);
        int nx=find(x);
        int ny=find(y);
        if(str=='M')
        {
            if(nx!=ny)
            {
                ff[nx]=ny;
                len[nx]+=dis[ny];
                dis[ny]+=dis[nx];
                dis[nx]=1;
            }
        }
        else
        {
            if(nx!=ny)
            {
                printf("-1\n");
                continue;
            }
            if(len[x]>len[y])
                printf("%d\n",len[x]-len[y]-1);
            else
                printf("%d\n",len[y]-len[x]-1);
        }
    }
    return 0;
}

 //刚开始还不会带权并查集,水过去的代码
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false)
#define maxn 30005
#define INF 1000000005
#define ll long long

int path[maxn];//记录路径
int ff[maxn],dis[maxn],out[maxn],len[maxn];
//out为i队列最外面的数字是什么

int find(int x)
{
    return x==ff[x]?x:ff[x]=find(ff[x]);
}

void read(int &x)
{
    x=0;
    bool flag=0;
    char ch=getchar();
    if(ch=='-') flag=1;
    while(ch<'0'||ch>'9')ch=getchar();
    while(ch>='0'&&ch<='9')x*=10,x+=ch-'0',ch=getchar();
    if(flag) x=-x;
}

int main()
{
    int n;
    read(n);
    for(int i=0; i<=maxn; i++)
        ff[i]=i,out[i]=i,dis[i]=1,path[i]=i;

    for(int i=0; i<n; i++)
    {
        char str;
        scanf(" %c",&str);
        int x,y;
        read(x),read(y);
        int nx=find(x);
        int ny=find(y);
        if(str=='M')
        {
            if(nx!=ny)
            {
                ff[nx]=ny;
                path[nx]=out[ny];
                int t=out[nx];
//对这条链的距离进行更新,所有值都更新了,所以慢啊
                while(t!=out[ny]) 
                {
                    len[t]+=dis[ny];
                    t=path[t];
                }
                out[ny]=out[nx];
                dis[ny]+=dis[nx];
                dis[nx]=1;
            }
        }
        else
        {
            if(nx!=ny)
                printf("-1\n");
            else
                printf("%d\n",abs(len[x]-len[y])-1);
        }

    }
    return 0;
}