zoukankan      html  css  js  c++  java
  • “扩展域”与"边带权"的并查集

    https://www.luogu.org/problemnew/show/P1196 

    银河英雄传说

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=30005;
    int f[maxn],d[maxn],s[maxn]; // f[i]用来记录i节点的根 d[i]记录i所在集合的前面有几个节点 s[i]记录s所在集合中节点的总大小 
    int n;
    void init()//初始化
    {
        for(int i=1; i<=30000; i++)
        {
            f[i]=i;
            d[i]=0;// 初始每个节点前面视为0,每个节点自成一个集合大小为1 
            s[i]=1;
        }
    }
    int getf(int a)
    {
        if(a==f[a]) return a;
        int root=getf(f[a]);   
        d[a]+=d[f[a]]; // 在将a节点指向新的根节点时,将d[a]更新为从a到根的距离 
        return f[a]=root; // 压缩路径 
    }
    void merge(int a, int b)
    {
        int t1,t2;
        t1=getf(a);
        t2=getf(b);  
        f[t2]=t1;//靠左原则,将t2合并到t1上
        d[t2]=s[t1];// 注意顺序 合并之后t1的大小为t1+t2的和,将d[t2]的距离更新为之前s[t1]的大小 
        s[t1]+=s[t2];
    }
    int main()
    {
        init();
        int t;
        cin>>t;
        char c;
        int m,n;
        for(int i=1; i<=t; i++)
        {
            cin>>c>>m>>n;
            if(c=='C')
            {
                if(getf(m)!=getf(n))
                    cout<<"-1"<<endl;
                else
                    cout<<abs(d[m]-d[n])-1<<endl;// 战舰之间的距离为两者相减的绝对值再减1 
            }
            else
                merge(n,m);// 合并两列的战舰 
        }
        return 0;
    }
  • 相关阅读:
    《你一定爱读的极简欧洲史》
    PAT 1051. 复数乘法
    PAT 1050. 螺旋矩阵
    PAT 1049. 数列的片段和
    PAT 1048. 数字加密
    PAT 1047. 编程团体赛
    PAT 1046. 划拳
    PAT 1045. 快速排序
    PAT 1044. 火星数字
    PAT 1043. 输出PATest
  • 原文地址:https://www.cnblogs.com/dongdong25800/p/10519904.html
Copyright © 2011-2022 走看看