The 14th Huazhong University of Science and Technology Programming Contest C Professional Manager [Union search delete / virtual point]

题目描述 
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



Meaning: There are four operations on trees.


1 uv , which merges the forest containing the u-th tree and the forest containing the v-th tree ;

u , separating the u-th tree from the forest;

3 u , query the size of the forest containing the u-th tree;

4 uv , to query whether the u-th tree and the v-th tree are in the same forest.

[Analysis]: Create a number w for each point. Deleting a point is equivalent to changing the number w of the point. It is also equivalent to constructing a new point.

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<string>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<set>
#define LL long long
#define INF 0xffffff
using namespace std;
const double pi = 2 * acos (0.0);
const int maxn = 2e5+10;
int n,m;
int p[maxn];
int s[maxn];
int w[maxn];
  
void init()
{
    for(int i=1;i<=maxn;i++) //这里必须是maxn,其他的好像不行
    {
        p[i] = i;
        w[i] = i;
        s[i] = 1;
    }
}
int Find(int x)
{
    return x==p[x]?x:p[x]=Find(p[x]);
}
void Union(int x,int y)
{
    int fx = Find(x);
    int fy = Find(y);
    if(fx!=fy)
    {
        p[fx] = fy;
        s[fy] += s[fx];
        //printf("size=%d\n",s[fy]);
    }
}
  
int main()
{
    int T;
    cin >> T;
    int k =1;
    while(T--)
    {
        printf("Case #%d:\n",k++);
        init();
       
        cin >> n >> m;
        int cnt = n;
        while(m--)
        {
            int op,u,v;
            scanf("%d",&op);
            if(op==1)
            {
                scanf("%d%d",&u,&v);
                Union(w[u],w[v]);
            }
            else if(op==2)
            {
                scanf("%d",&u);
                s[Find(w[u])]--;
                w[u] = ++cnt;
            }
            else if(op==3)
            {
                scanf("%d",&u);
                printf("%d\n",s[Find(w[u])]);
            }
            else{
                scanf("%d%d",&u,&v);
                if(Find(w[u])==Find(w[v]))
                    printf("YES\n");
                else printf("NO\n");
            }
        }
    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325175004&siteId=291194637