zoukankan      html  css  js  c++  java
  • P1196 [NOI2002]银河英雄传说[带权并查集]

    P1196 [NOI2002]银河英雄传说


    对于任意两艘舰,查询是否在同一列就是看在不在同一集合,并查集。询问距离的话,把每个点和他父亲的连边带上权值表示距离(父亲不一定就是前一艘舰),查询时会顺便压缩路径,一路回来会把所有点直接连边向根节点,这时边权改为他父亲(已直指根节点)的dis加上自己到父亲的dis,再连边向根。所以每次询问会把两个点到根的距离处理好,就可以出结果了。对于路径已压缩的点再查也不会出错。

    然后是合并问题。将x的根要并到y集合中,而x的根迟早是要被压缩路径的,不妨现在就把他连一个边到y的根节点权值是y集合战舰数量(也就是把x根接在y最后,其到队首的距离)。

    上述均摊复杂度$O(NlogN)$,然后可以加一些合并的优化什么的,复杂度基本就是$O(Nα(N))$了。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<algorithm>
     6 #include<queue>
     7 #define dbg(x) cerr<<#x<<" = "<<x<<endl
     8 #define ddbg(x,y) cerr<<#x<<" = "<<x<<"   "<<#y<<" = "<<y<<endl
     9 using namespace std;
    10 typedef long long ll;
    11 template<typename T>inline char MIN(T&A,T B){return A>B?A=B,1:0;}
    12 template<typename T>inline char MAX(T&A,T B){return A<B?A=B,1:0;}
    13 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
    14 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
    15 template<typename T>inline T _abs(T A){return A<0?-A:A;}
    16 template<typename T>inline T read(T&x){
    17     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
    18     while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
    19 }
    20 const int N=30000+7;
    21 int fa[N],dis[N],siz[N],T,x,y;
    22 char s[3];
    23 inline int Get(int x){
    24     if(fa[x]==x)return x;
    25     int ret=Get(fa[x]);
    26     dis[x]+=dis[fa[x]];
    27     return fa[x]=ret;
    28 }
    29 inline void Merge(int x,int y){
    30     int fx=Get(x),fy=Get(y);
    31     if(siz[fx]>siz[fy])x^=y^=x^=y;//按秩合并的优化 
    32     fa[fx]=fy,dis[fx]=siz[fy],siz[fy]+=siz[fx];
    33 }
    34 
    35 int main(){//freopen("test.in","r",stdin);//freopen("test.out","w",stdout);
    36     read(T);
    37     for(register int i=1;i<=3e4;++i)fa[i]=i,siz[i]=1;//dis[i]=0;
    38     while(T--){
    39         scanf("%s",s);read(x),read(y);
    40         if(s[0]=='M')Merge(x,y);
    41         else Get(x)^Get(y)?printf("-1
    "):printf("%d
    ",_abs(dis[x]-dis[y])-1);
    42     }
    43     return 0;
    44 }
  • 相关阅读:
    十一、 Façade外观(结构型模式)
    十七、 Mediator 中介者(行为型模式)
    十三、 Proxy代理(结构型模式)
    也谈.net平台的委托扩展篇
    也谈.net平台的委托基本篇
    十六、 Interpreter 解释器(行为型模式)
    十四、 Template Method模板方法(行为型模式)
    十八、 Iterator 迭代器(行为型模式)
    十五、 Command 命令(行为型模式)
    十二、 Flyweight享元(结构型模式)
  • 原文地址:https://www.cnblogs.com/saigyouji-yuyuko/p/10625199.html
Copyright © 2011-2022 走看看