1. 程式人生 > >牛客Professional Manager(並查集)

牛客Professional Manager(並查集)

sam 構造 tin whether closed 模板題 main ont 父親

t’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

這是一道有點宇宙不同的並查集模板題,與其他不同的是多了個刪除操作,那麽我們該怎麽做呢? 可以想到的是直接把要刪除的點的父親結點改成是自己,但是,如果這個點有子節點怎麽辦? 很顯然,這種方法就無法做了,
我們可以給每個點都給他們一個編號,刪除點,就相當於該點的編號改變就可以了,也是相當於構造新點
AC代碼
技術分享圖片
#include<stdio.h>
int n,f[200001],d[200001],h[200001],now;
///f為並查集,d為編號,h為高度
int findd(int x)///查找父節點
{
    if(f[x]!=x)
        f[x]=findd(f[x]);
    return f[x];

}
void init ()
{
    for(int k=1 ;k<=n ;k++)
    {
        f[k]=k;
        d[k]=k;
        h[k]=1;
    }
}
///合並
void HB(int u,int v)
{
        u=d[u],v=d[v];
        u=findd(u),v=findd(v);
        if(u==v)
        return ;
        f[u]=v;
        h[v]+=h[u];
}
///刪除
void SC(int u)
{
    int v;
     v=d[u];
    v=findd(v);
    h[v]--;
    ++now;
    d[u]=now;
    f[now]=now;h[now]=1;
}

int main()
{
    int t,i,q,x,v,u;
    scanf("%d",&t);
    for(i=1 ;i<=t; i++)
    {
        printf("Case #%d:\n",i);
        scanf("%d%d",&n,&q);
        now=n;
        init();
        while(q--)
        {
            scanf("%d",&x);
            if(x==1)
            {
                scanf("%d%d",&u,&v);
                HB(u,v);

            }
            if(x==2)
            {
                scanf("%d",&u);
               SC(u);

            }
            if(x==3)
            {
                scanf("%d",&u);
                u=d[u];u=findd(u);

                printf("%d\n",h[u]);

            }
            if(x==4)
            {
                scanf("%d%d",&u,&v);
                u=d[u];v=d[v];
                u=findd(u);v=findd(v);
                if(u==v)
                    printf("YES\n");
                else
                    printf("NO\n");
            }

        }
    }
    return 0;
}
View Code

牛客Professional Manager(並查集)