zoukankan      html  css  js  c++  java
  • 牛客Professional Manager(并查集)

    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:
    ",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
    ",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
    ");
                    else
                        printf("NO
    ");
                }
    
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    关于《大道至简》第四章的收获
    关于《大道至简》第三章的收获
    关于《大道至简》第二章的收获
    关于《大道至简》第一章的收获
    【模板】AC自动机(加强版)
    求第 i 个素数 Meissel Lehmer Algorithm + 二分 【模板】
    Meissel Lehmer Algorithm 求前n个数中素数个数 【模板】
    黑匣子_NOI导刊2010提高(06) Splay Tree
    CF446B DZY Loves Modification 优先队列
    CF446A DZY Loves Sequences 简单dp
  • 原文地址:https://www.cnblogs.com/shuaihui520/p/8974030.html
Copyright © 2011-2022 走看看