zoukankan      html  css  js  c++  java
  • 【NOI2002】银河英雄传说

    这是一道带权并查集的题目。

    我们维护三个数组,f[x]表示节点x所在集合的代表元素(相当于合并之后的树根),size[x]表示以x为代表元素的集合的大小是多少(相当于一列战舰的数量),d[x]表示在这一列战舰中,x前面的战舰有多少。

    因此对于每一次询问,答案就是|d[x]-d[y]|-1.

    我们怎样维护这三个数组呢?其中第一个数组的维护很简单,就是并查集的维护,我们重点考虑后两个数组的维护。

    在路径压缩时,在把x直接指向树根的同时,我们把d[x]更新为x到树根的距离,这样我们在并查集的find函数中就可以维护d,

    而对于size的维护,我们在合并时直接将前一段战舰所在的size加上后一段的size即可。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <cmath>
     6 using namespace std;
     7 int t;
     8 int f[30010],size[30010],d[300010];
     9 int find(int x) {
    10     if(f[x]==x) return x;
    11     int xx=find(f[x]);
    12     d[x]+=d[f[x]];
    13     return f[x]=xx;
    14 }
    15 int main() {
    16     cin>>t;
    17     for(int i=1;i<=30000;i++) {
    18         size[i]=1;
    19         f[i]=i;
    20         d[i]=0;
    21     }
    22     while(t--) {
    23         char c;
    24         int x,y;
    25         cin>>c>>x>>y;
    26         int fx=find(x);
    27         int fy=find(y);
    28         if(c=='M') {
    29             f[fx]=fy;
    30             d[fx]=size[fy];
    31             size[fy]+=size[fx];
    32         }
    33         else {
    34             if(f[x]!=f[y]) puts("-1");
    35             else printf("%d
    ",abs(d[x]-d[y])-1);
    36         }
    37     }
    38     return 0;
    39 }
    AC Code
  • 相关阅读:
    JavaScript之数学对象Math
    JavaScript之数据类型转换
    JavaScript之操作符
    JavaScript之基本语句
    JavaScript之基本概念(二)
    JavaScript之基本概念(一)
    使用velero进行kubernetes灾备
    minikube配置CRI-O作为runtime并指定flannel插件
    使用thanos管理Prometheus持久化数据
    linux开启tcp_timestamps和tcp_tw_recycle引发的问题研究
  • 原文地址:https://www.cnblogs.com/shl-blog/p/10803705.html
Copyright © 2011-2022 走看看