计蒜客 接龙 (带权并查集模板题)

题目链接:https://www.jisuanke.com/course/615/28116

题目大意:通过一系列的合并操作,然后求解出两点之间的距离。

题目思路:我们可以很容易的统计俩张卡片是否在同一个队列中,用并查集就可以了。关键是怎么计算,在一个队列中的俩个卡片之间卡片数目,只要维护一下每个卡片到队列头的卡片数目就好了。在计算同一队列中的俩个卡片之间卡片数目,只要把俩个卡片到队列头的卡片数目做差就可以了。

学到的东西:加权并查集。

代码:

//加权并查集模板题,需要整理

#include 
using namespace std;
const int maxn=5e6+2;
int pre[maxn];
int val[maxn];//存储到根节点距离的数组
int Size[maxn];//存储在该节点下集合的大小
void build(int n)
{
    for(int i=0;i<=n;i++)
        pre[i]=i,val[i]=0,Size[i]=1;
}

int find(int x)
{
    if(pre[x]==x) return x;

    int y=pre[x];
    pre[x]=find(y);
    val[x]+=val[y];//x到根节点的距离就等本身加上双亲到根节点的距离

    return pre[x];
}

bool join(int x,int y)
{
    int p=find(x);
    int q=find(y);
    if(p!=q){
        pre[p]=q;
        //val[q]+=val[p];
        val[p]=Size[q];//p到根节点的位置,就等于q集合的大小
        Size[q]+=Size[p];//q集合的大小增加了,p集合加入了进来
        return true;
    }
    return false;
}
int main()
{
    int n;scanf("%d",&n);
    build(n);
    while(n--){
        char c;
        int x,y;
        cin>>c>>x>>y;
        if(c=='M'){
            join(x,y);
        }
        else{
            if(find(x)!=find(y)) cout<<"-1"<


你可能感兴趣的:(数据结构--并查集)