题解 LuoguP2342 【叠积木】

并查集,只需要稍微改变一下合并和查找的代码就可以了。

\(Code:\)

#pragma GCC diagnostic error "-std=c++11"
#include <cstdio>
#include <iostream>
#include <string>
using namespace std;
template<class T>void r(T &a)
{
    T s=0,w=1;a=0;char ch=getc(stdin);
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getc(stdin);}
    while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getc(stdin);}
    a=w*s;
}
template<class T,class... Y>void r(T& t,Y&... a){r(t);r(a...);}
struct bcj
{
    int father[30010],num[30010],up[30010];
    //num[i]表示以i为最顶积木的堆的积木数
    //up[i]表示i这个积木上面有几块积木
    //所以答案为num[find(i)]-up[i]-1
    void start(int n)
    {for(int i=0;i<=n;i++)father[i]=i,num[i]=1,up[i]=0;}
    int find(int x)
    {if(father[x]!=x){int a=find(father[x]);up[x]+=up[father[x]];
    return father[x]=a;}else return x;}
    void unionn(int x,int y)
    {x=find(x);y=find(y);if(x!=y){up[y]=num[x];father[y]=x;
    num[x]+=num[y];num[y]=0;}}
    bool judge(int x,int y)
    {if(find(x)==find(y))return true;return false;}
}uf;
int main()
{
    int p;
    r(p);
    uf.start(30000);
    for(int i=1;i<=p;i++)
    {
        char c;
        int x,y;
        cin>>c;
        if(c=='M')
        {
            r(x,y);
            uf.unionn(x,y);
        }
        else
        {
            r(x);
            printf("%d\n",uf.num[uf.find(x)]-uf.up[x]-1);
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Naive-Cat/p/10664072.html