第十四届华中科技大学程序设计竞赛 C-Professional Manager 【并查集】

题目描述 
It’s universally acknowledged that there’re innumerable trees in the campus of HUST. 


Thus a professional tree manager is needed. Your task is to write a program to help manage the trees. 
Initially, there are n forests and for the i-th forest there is only the i-th tree in it. Given four kinds of operations.
1 u v, merge the forest containing the u-th tree and the forest containing the v-th tree;
2 u, separate the u-th tree from its forest;
3 u, query the size of the forest which contains the u-th tree;
4 u v, query whether the u-th tree and the v-th tree are in the same forest.
输入描述:
The first line contains an integer T, indicating the number of testcases.
In each test case:
The first line contains two integers N and Q, indicating the number of initial forests and the number of operations.
Then Q lines follow, and each line describes an operation.
输出描述:
For each test cases, the first line should be "Case #i:", where i indicate the test case i.
For each query 3, print a integer in a single line.
For each query 4, print "YES" or "NO" in a single line.
示例1
输入


1
10 8
3 1
4 1 2
1 1 2
3 1
4 1 2
2 1
3 1
4 1 2
输出


Case #1:
1
NO
2
YES
1

NO大写的门


简单的并查集应用,但是要注意他的二操作,以为对多开很多集合,所以很可能会re,注意要把数组开到范围的两倍大小;

#include<bits/stdc++.h>
using namespace std;
const int MAX = 2e5 + 7;
int pre[MAX];
int sum[MAX];
int place[MAX];
int n, m;
int findx(int x)
{
    return x == pre[x] ? x : pre[x] = findx(pre[x]);
}
int main()
{
    int N;
    int kase = 0;
    scanf("%d", &N);
    while(N--)
    {
        printf("Case #%d:\n", ++kase);
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i++)
        {
            pre[i] = i;
            sum[i] = 1;
            place[i] = i;
        }
        int pos = n;
        while(m--)
        {
            int x, y, s;
            scanf("%d", &s);
            if(s == 1)
            {
                scanf("%d%d", &x, &y);
                x = place[x];
                y = place[y];
                x = findx(x);
                y = findx(y);
                if(x != y)
                {
                    pre[x] = y;
                    sum[y] += sum[x];

                }
            }
            if(s == 2)
            {
                scanf("%d", &x);
                y = place[x];
                y = findx(y);
                sum[y]--;
                pos++;
                sum[pos] = 1;
                pre[pos] = pos;
                place[x] = pos;
            }
            if(s == 3)
            {
                scanf("%d", &x);
                x = place[x];
                x = findx(x);
                printf("%d\n", sum[x]);
            }
            if(s == 4)
            {
                scanf("%d%d", &x, &y);
                x = place[x];
                y = place[y];
                x = findx(x);
                y = findx(y);
                if(x == y)
                    puts("YES");
                else
                    puts("NO");
            }
        }
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/head_hard/article/details/80151139
今日推荐