题目链接:https://www.luogu.org/problemnew/show/P1196

题意:

  有30000个战舰队列,编号1...30000。

  有30000艘战舰,编号1...30000,初始时第i艘战舰在第i个战舰队列中。

  然后t个操作:

    (1)M i j:将战舰i所在的队列整体接到战舰j所在队列的尾部。

    (2)C i j:询问战舰i,j之间有多少艘战舰。若i,j不在同一队列中,输出-1。

题解:

  dis[i]表示战舰i与par[i]之间的距离。

  siz[i]表示战舰i所在队列的大小。

  find(x):

    old为原本的par[x],now为路径压缩后的par[x]。

    此时关系为:x -> old -> now

    所以此时dis[x] = dis(x to old) + dis(old to now)

    即:dis[x] += dis[old]

  unite(x,y):

    px,py分别为x,y的真正祖先。

    因为是将px的整个队列接到了py队列的后面

    所以dis[px]=siz[py], siz[py]+=siz[px]

    (因为程序中只会用到队首的siz值,所以只更新py的siz就行了)

  query(x,y):

    如果不在同一集合中直接return -1.

    先让x,y找到它们的真正祖先。

    然后答案就是abs(dis[x]-dis[y]) - 1

AC Code:

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #define MAX_N 30005
  5.  
  6. using namespace std;
  7.  
  8. int t;
  9. int par[MAX_N];
  10. int dis[MAX_N];
  11. int siz[MAX_N];
  12.  
  13. void init()
  14. {
  15. for(int i=;i<=;i++)
  16. {
  17. par[i]=i;
  18. dis[i]=;
  19. siz[i]=;
  20. }
  21. }
  22.  
  23. int find(int x)
  24. {
  25. if(par[x]!=x)
  26. {
  27. int old=par[x];
  28. int now=find(par[x]);
  29. par[x]=now;
  30. dis[x]+=dis[old];
  31. }
  32. return par[x];
  33. }
  34.  
  35. void unite(int x,int y)
  36. {
  37. int px=find(x);
  38. int py=find(y);
  39. if(px==py) return;
  40. par[px]=py;
  41. dis[px]=siz[py];
  42. siz[py]+=siz[px];
  43. }
  44.  
  45. bool same(int x,int y)
  46. {
  47. return find(x)==find(y);
  48. }
  49.  
  50. inline int abs(int x)
  51. {
  52. return x> ? x : -x;
  53. }
  54.  
  55. int query(int i,int j)
  56. {
  57. if(!same(i,j)) return -;
  58. find(i); find(j);
  59. return abs(dis[i]-dis[j])-;
  60. }
  61.  
  62. int main()
  63. {
  64. init();
  65. cin>>t;
  66. char opt;
  67. int i,j;
  68. while(t--)
  69. {
  70. cin>>opt>>i>>j;
  71. if(opt=='M') unite(i,j);
  72. else cout<<query(i,j)<<endl;
  73. }
  74. }

Luogu P1196 [NOI2002]银河英雄传说:带权并查集的更多相关文章

  1. Luogu P1196 [NOI2002]银河英雄传说

    一年没写博客了(滑稽). 这道题很玄学,导致自己都有一个坑人的问题求解.如果有大佬有能力求帮助:https://www.luogu.org/discuss/show?postid=30231 再来讲一 ...

  2. 【洛谷】P1196 [NOI2002]银河英雄传说【带权并查集】

    P1196 [NOI2002]银河英雄传说 题目描述 公元五八○一年,地球居民迁至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的 ...

  3. 解题报告:luogu P1196 [NOI2002]银河英雄传说

    由于并查集让我很自闭(其实是我太弱了),所以学习了加权并查集,这是例题: 题目链接:P1196 [NOI2002]银河英雄传说 不是很简单,但对于大佬还是签到题. 合并与路径压缩时直接维护\(dis[ ...

  4. P1196 [NOI2002]银河英雄传说 【带权并查集】

    思路 用sum记录每个舰队的战舰数量, tohead 记录当前舰离舰首的距离,那么求任意两舰之间有多少舰显然就是 abs( tohead[i] - tohead[j] ) - 1: CODE #inc ...

  5. 洛谷——P1196 [NOI2002]银河英雄传说

    P1196 [NOI2002]银河英雄传说 题目大意: 给你一个序列,支持两种操作: 合并指令为$M_{i,j}$j​,含义为第i号战舰所在的整个战舰队列,作为一个整体(头在前尾在后)接至第j号战舰所 ...

  6. P1196 [NOI2002]银河英雄传说

    题目描述 公元五八○一年,地球居民迁至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发战争.泰山压顶 ...

  7. [Luogu 1196] NOI2002 银河英雄传说

    [Luogu 1196] NOI2002 银河英雄传说 话说十六年前的 NOI 真简单... 我一开始还把题看错了- 题意:一群人,每个人各自成一队,每次命令让两队首位相接合成一队,每次询问问你某两个 ...

  8. 洛谷P1196 [NOI2002] 银河英雄传说

    #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #includ ...

  9. 洛谷 P1196 [NOI2002]银河英雄传说

    题意简述 有30000列,每列都有一艘战舰,编号1~30000 有2种操作: 1.将一列的战舰运到另一列 2.询问两个战舰是否在同一列,如果是,求出它们之间的距离 题解思路 并查集, 维护每个点x离自 ...

随机推荐

  1. __must_check必须处理函数返回值

    include/linux/compiler-gcc4.h  #define __must_check            __attribute__((warn_unused_result)) _ ...

  2. android 蓝牙低耗能(LBE)技术介绍

    蓝牙低能耗(BLE)技术是低成本.短距离.可互操作的鲁棒性无线技术.工作在免许可的2.4GHz ISM射频频段.它从一開始就设计为超低功耗(ULP)无线技术. 它利用很多智能手段最大限度地减少功耗. ...

  3. Centos7 install RabbitMQ

    安装rabbitmq 需要环境上有erlang,没有安装的可以参照下面的内容进行安装: https://www.erlang-solutions.com/resources/download.html ...

  4. GreenDao学习

    官方文档地址:http://greenrobot.org/greendao/documentation//introduction/ 英语不好的可以使用谷歌翻译,很轻松的看懂文档,不需要FQ. 看不懂 ...

  5. 用代码构造PreferenceScreen

    在PreferenceFregment中构造界面,简单省事的方法就是使用findPreference然后在xml里把UI写好.在代码中动态的添加UI内容也是需要的.核心代码是: PreferenceS ...

  6. solr原理

    1.solr原理: 我本人的理解:solr是为解决高性能的全文索引而出现的,它将用户输入的关键字进行智能分解,分解成一个个词,过滤掉一些多余的停词及空格等,比如,“在”.“里面”.“也”.“的”.“它 ...

  7. Keepalived 集群在Linux下的搭建

    [概述]:Keepalived 是一个免费开源的,用C编写.主要提供loadbalancing(负载均衡)和 high-availability(高可用)功能,负载均衡实现需要依赖Linux的虚拟服务 ...

  8. yii2.0 中的队列

    a yii2 extension to make simple to use queue. yii2-queue让队列的使用在yii2中变得更轻松,她为各种队列组件的使用提供了一个标准的接口,您只需要 ...

  9. 【BZOJ3488】[ONTAK2010]Highways 扫描线+树状数组

    [BZOJ3488][ONTAK2010]Highways Description 给一棵n个点的树以及m条额外的双向边q次询问,统计满足以下条件的u到v的路径:恰经过一条额外的边不经过树上u到v的路 ...

  10. TFS中工作项的定制- 字段功能定义

    参考,翻译此页面All FIELD XML Elements Reference(http://msdn.microsoft.com/en-us/library/ms194953.aspx) 对于每一 ...