Luogu P1196 [NOI2002]银河英雄传说:带权并查集
题目链接: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:
- #include <iostream>
- #include <stdio.h>
- #include <string.h>
- #define MAX_N 30005
- using namespace std;
- int t;
- int par[MAX_N];
- int dis[MAX_N];
- int siz[MAX_N];
- void init()
- {
- for(int i=;i<=;i++)
- {
- par[i]=i;
- dis[i]=;
- siz[i]=;
- }
- }
- int find(int x)
- {
- if(par[x]!=x)
- {
- int old=par[x];
- int now=find(par[x]);
- par[x]=now;
- dis[x]+=dis[old];
- }
- return par[x];
- }
- void unite(int x,int y)
- {
- int px=find(x);
- int py=find(y);
- if(px==py) return;
- par[px]=py;
- dis[px]=siz[py];
- siz[py]+=siz[px];
- }
- bool same(int x,int y)
- {
- return find(x)==find(y);
- }
- inline int abs(int x)
- {
- return x> ? x : -x;
- }
- int query(int i,int j)
- {
- if(!same(i,j)) return -;
- find(i); find(j);
- return abs(dis[i]-dis[j])-;
- }
- int main()
- {
- init();
- cin>>t;
- char opt;
- int i,j;
- while(t--)
- {
- cin>>opt>>i>>j;
- if(opt=='M') unite(i,j);
- else cout<<query(i,j)<<endl;
- }
- }
Luogu P1196 [NOI2002]银河英雄传说:带权并查集的更多相关文章
- Luogu P1196 [NOI2002]银河英雄传说
一年没写博客了(滑稽). 这道题很玄学,导致自己都有一个坑人的问题求解.如果有大佬有能力求帮助:https://www.luogu.org/discuss/show?postid=30231 再来讲一 ...
- 【洛谷】P1196 [NOI2002]银河英雄传说【带权并查集】
P1196 [NOI2002]银河英雄传说 题目描述 公元五八○一年,地球居民迁至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的 ...
- 解题报告:luogu P1196 [NOI2002]银河英雄传说
由于并查集让我很自闭(其实是我太弱了),所以学习了加权并查集,这是例题: 题目链接:P1196 [NOI2002]银河英雄传说 不是很简单,但对于大佬还是签到题. 合并与路径压缩时直接维护\(dis[ ...
- P1196 [NOI2002]银河英雄传说 【带权并查集】
思路 用sum记录每个舰队的战舰数量, tohead 记录当前舰离舰首的距离,那么求任意两舰之间有多少舰显然就是 abs( tohead[i] - tohead[j] ) - 1: CODE #inc ...
- 洛谷——P1196 [NOI2002]银河英雄传说
P1196 [NOI2002]银河英雄传说 题目大意: 给你一个序列,支持两种操作: 合并指令为$M_{i,j}$j,含义为第i号战舰所在的整个战舰队列,作为一个整体(头在前尾在后)接至第j号战舰所 ...
- P1196 [NOI2002]银河英雄传说
题目描述 公元五八○一年,地球居民迁至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发战争.泰山压顶 ...
- [Luogu 1196] NOI2002 银河英雄传说
[Luogu 1196] NOI2002 银河英雄传说 话说十六年前的 NOI 真简单... 我一开始还把题看错了- 题意:一群人,每个人各自成一队,每次命令让两队首位相接合成一队,每次询问问你某两个 ...
- 洛谷P1196 [NOI2002] 银河英雄传说
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #includ ...
- 洛谷 P1196 [NOI2002]银河英雄传说
题意简述 有30000列,每列都有一艘战舰,编号1~30000 有2种操作: 1.将一列的战舰运到另一列 2.询问两个战舰是否在同一列,如果是,求出它们之间的距离 题解思路 并查集, 维护每个点x离自 ...
随机推荐
- __must_check必须处理函数返回值
include/linux/compiler-gcc4.h #define __must_check __attribute__((warn_unused_result)) _ ...
- android 蓝牙低耗能(LBE)技术介绍
蓝牙低能耗(BLE)技术是低成本.短距离.可互操作的鲁棒性无线技术.工作在免许可的2.4GHz ISM射频频段.它从一開始就设计为超低功耗(ULP)无线技术. 它利用很多智能手段最大限度地减少功耗. ...
- Centos7 install RabbitMQ
安装rabbitmq 需要环境上有erlang,没有安装的可以参照下面的内容进行安装: https://www.erlang-solutions.com/resources/download.html ...
- GreenDao学习
官方文档地址:http://greenrobot.org/greendao/documentation//introduction/ 英语不好的可以使用谷歌翻译,很轻松的看懂文档,不需要FQ. 看不懂 ...
- 用代码构造PreferenceScreen
在PreferenceFregment中构造界面,简单省事的方法就是使用findPreference然后在xml里把UI写好.在代码中动态的添加UI内容也是需要的.核心代码是: PreferenceS ...
- solr原理
1.solr原理: 我本人的理解:solr是为解决高性能的全文索引而出现的,它将用户输入的关键字进行智能分解,分解成一个个词,过滤掉一些多余的停词及空格等,比如,“在”.“里面”.“也”.“的”.“它 ...
- Keepalived 集群在Linux下的搭建
[概述]:Keepalived 是一个免费开源的,用C编写.主要提供loadbalancing(负载均衡)和 high-availability(高可用)功能,负载均衡实现需要依赖Linux的虚拟服务 ...
- yii2.0 中的队列
a yii2 extension to make simple to use queue. yii2-queue让队列的使用在yii2中变得更轻松,她为各种队列组件的使用提供了一个标准的接口,您只需要 ...
- 【BZOJ3488】[ONTAK2010]Highways 扫描线+树状数组
[BZOJ3488][ONTAK2010]Highways Description 给一棵n个点的树以及m条额外的双向边q次询问,统计满足以下条件的u到v的路径:恰经过一条额外的边不经过树上u到v的路 ...
- TFS中工作项的定制- 字段功能定义
参考,翻译此页面All FIELD XML Elements Reference(http://msdn.microsoft.com/en-us/library/ms194953.aspx) 对于每一 ...