zoukankan      html  css  js  c++  java
  • 《算法竞赛进阶指南》0x41并查集 银河英雄传说(边带权并查集)

    题目链接:https://www.acwing.com/problem/content/240/

    题目给出初始时刻的n个队伍,每个队伍只有一个对应编号的i,操作有两种,一种是将第i列的接在第j列后面,一种是查询两个人是否在同一列,在同一列的话给出两者之间隔了多少人。

    由于每一列都是一棵树,所以可以通过并查集进行求解,期间需要维护x到fx的距离,注意:每次fx改变的时候就要维护dx,并且需要一个辅助数组sizex在根节点计算树的大小。

    代码:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    const int maxn = 30010;
    int f[maxn],siz[maxn];
    int d[maxn];//d[x]表示的是x到fx的路径长度 
    int n;
    int find(int x){
        if(x==f[x])return x;
        int root=find(f[x]);
        d[x]+=d[f[x]];//在没有路径压缩的情况下,d[x]表示的是指向前面结点的路径长度 
        return f[x]=root;
    }
    void merge(int x,int y){//将x拼接到y后面 
        int fx=find(x);
        int fy=find(y);
        if(x==y)return ;
        f[fx]=fy;//只有当fx改变的时候才改变d 
        d[fx]=siz[fy];
        siz[fy]+=siz[fx]; 
    }
    int main(){
        cin>>n;
        for(int i=1;i<=maxn-1;i++)f[i]=i,siz[i]=1; 
        string s;
        int a,b;
        for(int i=1;i<=n;i++){
            cin>>s>>a>>b;
            if(s[0]=='M')merge(a,b);
            if(s[0]=='C'){
                if(find(a)==find(b))printf("%d
    ",abs(d[a]-d[b])-1);
                else puts("-1");
            }
        }
        return 0;
    }
  • 相关阅读:
    HanTTS简单文档
    一张包含所有颜色的图片
    shiro整合SpringMVC基于xml
    设计模式-享元模式
    关于volatile关键字实现的个人理解
    重量级锁
    轻量级锁
    偏向锁
    Seata概念的总结
    苹果手机怎么把资源库的APP放到桌面
  • 原文地址:https://www.cnblogs.com/randy-lo/p/13293594.html
Copyright © 2011-2022 走看看