【数据结构】【基础】银河英雄传说

原题:https://www.acwing.com/problem/content/240/

思路:

  • 并查集实现:

使用范围:动态维护许多具有传递性的关系,能在无向图中维护节点之间的连通性。

根节点数组p初始化为自己,以及查询根节点函数find

int p[N], d[N];

int
find(int x) { if(p[x] != x) { int root = get(p[x]); d[x] += d[p[x]];//权值更新 p[x] = root; } return p[x]; }
  • 如何实现题目要求的操作

对于M操作,查询两个元素的根节点,将要移动的根节点赋值为另一个(连接在该列后),然后更新根节点的权值为该列已有元素的个数。为此我们还需要一个size数组来记录根节点的元素数目。

#include<iostream>

using namespace std;

const int N = 30050;

int p[N],d[N],sizex[N],n,m;

int get(int x)
{
    if(p[x] != x)
    {
        int root = get(p[x]);
        d[x] += d[p[x]];
        p[x] = root;
    }
    return p[x];
}

int main()
{
    int t;
    cin >> t;
    for(int i = 1; i <= N;i ++ ) p[i] = i, sizex[i] = 1;
    
    while(t -- )
    {
        char s[2];
        int x, y;
        scanf("%s%d%d",s, &x, &y);
        if(s[0] == 'M')
        {
            x = get(x), y = get(y);
            d[x] = sizex[y];
            sizex[y] += sizex[x];
            p[x] = y;
        }
        else
        {
            int fx = get(x), fy = get(y);
            if(fx == fy) printf("%d\n",max(0, abs(d[x] - d[y]) - 1));
            else printf("-1\n");
        }
    }
    return 0;
}

 

posted @ 2020-11-08 23:07  褪色回音  阅读(90)  评论(0)    收藏  举报