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离自 ...
随机推荐
- 笔试真题解析 ALBB-2015 系统project师研发笔试题
4)在小端序的机器中,假设 union X { int x; char y[4]; }; 假设 X a; a.x=0x11223344;//16进制 则:() y[0]=11 y[1] ...
- ntp服务及其配置
集群中使用NTP服务 简介 之前搭建zookeeper时报了一个错,我以为是ntp的问题,结果不是.这里详细学习一下如何在集群中使用ntp服务. 什么是ntp服务 来自ntp的百度百科: NTP服务器 ...
- spring roo初体验
1.下载spring-roo-2.0.0.M1,并执行如下命令,在/usr/local/bin下面建立一个roo的软连接 sudo ln -s /Users/pud/Documents/still ...
- shiro集成encache
针对多频次或者几乎不变的大数量的数据,我们可以通过缓存来实现,具体的比如说权限认证,这个,每次操作都需要权限认证,所以,这里添加encache注解.具体的认证过程是: 1,用户第一次访问用户权限信息, ...
- java高级之信号灯Semaphore
1.Semaphore概念 Semaphore是Java1.5之后提供的一种同步工具,Semaphore可以维护访问自身线程个数,并提供了同步机制.使用Semaphore可以控制同时访问资源的线程个数 ...
- Linux4_文件操作
以下操作都是在终端命令行: 1 apt-get install 应用名称,(---:apt-get是从Ubuntu的软件应用里自动下载) 如果你不知道下载,随便输入:java,javac,tree ...
- Android拍照生成缩略图
在Android 2.2版本中,新增了一个ThumbnailUtils工具类来是实现缩略图,此工具类的功能是强大的,使用是简单,它提供了一个常量和三个方法.利用这些常数和方法,可以轻松快捷的实现图片和 ...
- C++中面向对象的理解
1.对于OO(面向对象)的含义,并非每一个人的看法都是同样的. 即使在如今.假设问十个人,可能会得到15种不同的答案.差点儿全部的人都会允许继承和多态是OO中的概念.大多数人还会再加上封装. 另 ...
- js校验密码强度
网上转载的一段代码,留着以后用, js文件: //判断输入密码的类型 function CharMode(iN){ if (iN>=48 && iN <=57) //数字 ...
- GCD(st表+二分)
GCD Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submis ...