题目链接: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]银河英雄传说:带权并查集的更多相关文章

  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. lua学习笔记(六)

    (2012-04-12 23:32:35) 转载▼   函数  定义     function mytest(a,b,c) <函数体> end     mytest = function( ...

  2. 创建自己的Spring Boot Starter

    抽取通用模块作为项目的一个spring boot starter.可参照mybatis的写法. IDEA创建Empty Project并添加如下2个module,一个基本maven模块,另一个引入sp ...

  3. VMware网络连接 桥接、NAt、host-only模式

    如果你想利用VMWare安装虚拟机,或想创建一个与网内其他机器相隔离的虚拟系统,进行特殊的调试工作.此时,对虚拟系统网络连接模式的选择就非常重要了.如果你选择的工作模式不正确,就无法实现上述目的,也就 ...

  4. 题目3 : Fibonacci

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 Given a sequence {an}, how many non-empty sub-sequence of it ...

  5. PHP 使用 GeoLiteCity 库解析 IP 为地理位置

    关于把 IP 地址转换为地理位置可以使用网络上很多的 API,好处就是不用在本地存储一个 IP 数据库,而且一般网络上的 IP 库会自动更新,不利的地方就是太依赖于网络,性能表现也可能会弱些.比如像下 ...

  6. pip安装错误,用镜像

    Retrying (Retry(total=4, connect=None, read=None, redirect=None)) after connection broken by 'Connec ...

  7. PHP里的socket_recv方法解释

    以前一直经为PHP里没有低级的socket帧接收函数,看来是没看仔细,不过那些说明也太少了,(更令人气的里在英文版说明里的例子下有一句话:这个程序不能运行,因为没用listen函数,但在中文版里却没了 ...

  8. 算不算类似微信小程序

    这几天微信发布的微信里生成小程序,刷爆了朋友圈. 微信生成的小程序不用下载安装就能在手机里出现,即用即删. 想到这里,我想到苹果手机本身再带类似于微信的小程序的呈现方式,也可以即用即删,那是我在去年久 ...

  9. lua(注册c库)

    #include <iostream> #include <string.h> extern "C" { #include "lua-5.2.2/ ...

  10. HDFS上传机制