洛谷 题解 P1196 【[NOI2002]银河英雄传说】
并查集大难题。
看了题解之后才有思路,调了很久很久才AC,当然要写一篇题解来纪念一下。
先来分析一下这些指令的特点,很容易发现对于每个M指令,只可能一次移动整个队列,并且是把两个队列首尾相接合并成一个队列,不会出现把一个队列分开的情况,因此,我们必须要找到一个可以一次操作合并两个队列的方法。
再来看下C指令:判断飞船i和飞船j是否在同一列,若在,则输出它们中间隔了多少艘飞船。我们先只看判断是否在同一列,由于每列一开始都只有一艘飞船,之后开始合并,结合刚刚分析过的M指令,很容易就想到要用并查集来实现。
用fa[i]表示飞船i的祖先节点,即其所在列的队头。
看见多次求两个点的距离的问题,便想到用前缀和来实现:开一个g数组,g[i]表示飞船i到其所在队列队头的距离,然后飞船i和飞船j之间的飞船数量即为它们到队头的距离之差减一,就是abs(g[i]-g[j])-1。
我们来分析一下:对于原来的队头,它到队头的距离为0,当将它所在的队列移到另一个队列后面时,它到队头的距离就是排在它前面的飞船数,也就是合并前另一个队列的飞船数量。因此,就知道该怎样实现了,我们再建一个数组num,num[i]表示以i为队头的队列的飞船数量,初始时都是1,在每次合并的时候,fx为合并前飞船i的队头,fy为合并前飞船j的队头,每次合并时,先更新g[fx],即给它加上num[fy],然后开始合并,即fa[fx]=fy,最后更新num, num[fy]+= num[fx];num[fx]=0。
现在就差最后一步了:如何计算每个飞船到队头的距离。再来分析一下:对于任意一个飞船,我们都知道它的祖先(不一定是队头,但一定间接或直接指向队头),还知道距离它祖先的距离。对于每一个飞船,它到队头的距离,就等于它到它祖先的距离加上它祖先到队头的距离,而它的祖先到队头的距离,也可以变成类似的。可以递归实现,由于每一次更新都要用到已经更新完成的祖先到队头的距离,所以要先递归找到队头,然后在回溯的时候更新(g[i]+=g[fa[i]]),可以把这个过程和find的函数放在一起。
完整代码:
#include<bits/stdc++.h>
using namespace std;
const int MAXN=30000+10;
int T;
int fa[MAXN],num[MAXN],g[MAXN];
inline int read()
{
int tot=0;
char c=getchar();
while(c<'0'||c>'9')
c=getchar();
while(c>='0'&&c<='9')
{
tot=tot*10+c-'0';
c=getchar();
}
return tot;
}
inline int find(int k)
{
if(fa[k]==k)return k;
int grandfa=find(fa[k]);
g[k]+=g[fa[k]];
return fa[k]=grandfa;
}
int main()
{
T=read();
for(int i=1;i<=MAXN-10;i++)fa[i]=i,num[i]=1;
char c;
int x,y;
while(T--)
{
cin>>c;
x=read();y=read();
int fx=find(x),fy=find(y);
//cout<<c<<" "<<x<<" "<<y<<endl;
if(c=='M')
{
g[fx]+=num[fy];
fa[fx]=fy;
num[fy]+=num[fx];
num[fx]=0;
}
else
{
if(fx!=fy)cout<<-1<<endl;
else
cout<<abs(g[x]-g[y])-1<<endl;
}
//for(int i=1;i<=5;i++)cout<<fa[i]<<" ";cout<<endl;
}
return 0;
}
参考博文:https://www.luogu.org/blog/user24518/solution-p1196
洛谷 题解 P1196 【[NOI2002]银河英雄传说】的更多相关文章
- 【洛谷】P1196 [NOI2002]银河英雄传说【带权并查集】
P1196 [NOI2002]银河英雄传说 题目描述 公元五八○一年,地球居民迁至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的 ...
- 边带权并查集 学习笔记 & 洛谷P1196 [NOI2002] 银河英雄传说 题解
花了2h总算把边带权并查集整明白了qaq 1.边带权并查集的用途 众所周知,并查集擅长维护与可传递关系有关的信息.然而我们有时会发现并查集所维护的信息不够用,这时"边带权并查集"就 ...
- P1196 [NOI2002]银河英雄传说(并查集)
P1196 [NOI2002]银河英雄传说(并查集) 本题关键 用两个一维数组表示了一个稀疏的二维数组. 这两个一维数组一个表示祖先(就是最前面那个),一个表示距离祖先的距离. 并且还有一个关键点是, ...
- [洛谷P1196][NOI2002]银河英雄传说 - 带偏移量的并查集(1)
Description 公元五八〇一年,地球居民迁至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发 ...
- 洛谷OJ P1196 银河英雄传说(带权并查集)
题目描述 公元五八○一年,地球居民迁移至金牛座α第二行星,在那里发表银河联邦 创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发战争.泰山 ...
- 洛谷 题解 UVA572 【油田 Oil Deposits】
这是我在洛谷上的第一篇题解!!!!!!!! 这个其实很简单的 我是一只卡在了结束条件这里所以一直听取WA声一片,详细解释代码里见 #include<iostream> #include&l ...
- 洛谷 题解 P1600 【天天爱跑步】 (NOIP2016)
必须得说,这是一道难题(尤其对于我这样普及组205分的蒟蒻) 提交结果(NOIP2016 天天爱跑步): OJ名 编号 题目 状态 分数 总时间 内存 代码 / 答案文件 提交者 提交时间 Libre ...
- 洛谷题解P4314CPU监控--线段树
题目链接 https://www.luogu.org/problemnew/show/P4314 https://www.lydsy.com/JudgeOnline/problem.php?id=30 ...
- 洛谷P1196[NOI2002]银河英雄传说-并查集扩展
银河英雄传说 题意:在并查集的基础上,还要求出同一集合的两个点的距离 这道题用并查集自己是知道的,但是竟然可以这么骚的操作. 下面转自大佬的查详细题解 初见这道题,首先想到的方法当然是直接模拟,模拟每 ...
随机推荐
- SIGAI机器学习第五集 贝叶斯分类器
讲授贝叶斯公式.朴素贝叶斯分类器.正态贝叶斯分类器的原理.实现以及实际应用 大纲: 贝叶斯公式(直接用贝叶斯公式完成分类,计算一个样本的特征向量X属于每个类c的概率,这个计算是通过贝叶斯公式来完成的. ...
- Educational Codeforces Round 67 (Rated for Div. 2) B题【前缀+二分】【补题ING系列】
题意:给出一个字符串s, 可以从左往右拿走s的字符, 至少要到s的第几个位置才能拼成t 思路:用二维数组记录前缀,然后二分即可. #include<bits/stdc++.h> using ...
- Codeforces Round #590 (Div. 3)【D题:26棵树状数组维护字符出现次数】
A题 题意:给你 n 个数 , 你需要改变这些数使得这 n 个数的值相等 , 并且要求改变后所有数的和需大于等于原来的所有数字的和 , 然后输出满足题意且改变后最小的数值. AC代码: #includ ...
- Visual Studio Code:中文乱码
造冰箱的大熊猫@cnblogs 2019/11/3 在UTF环境下,用VSCode打开一个GB2312编码的文件,显示乱码怎么办? 1.窗口右下方会显示当前所使用的编码格式(下图中手型图标所在处UTF ...
- CMake学习- 使用批处理设置编译环境
批处理-.bat cd /d "%~dp0" mkdir build mkdir install cd build ..\cmake37\bin\cmake.exe -D WIN3 ...
- 三十、CentOS 7之systemd
一.系统启动流程 POST --> bootloader --> MBR工作 --> kernel(initramfs/initrd) --> ro rootfs --> ...
- 八、linux文件系统上的特殊权限 SUID 、GUID、Sticky
安全上下文 前提:进程有属主和属组,文件有属主和属组 任何一个可执行程序文件能不能启动为进程:取决发起者对程序文件是否拥有执行权限 启动为进程之后,其进程的属主为发起者:进程的属组为发起者所属的组 进 ...
- Java连接Memcached进行CRUD
参考这篇博文在本机安装了Memcached 在 Java 中常用的memcached有三个: Memcached Client for Java SpyMemcached XMemcached 这里使 ...
- spring事物不回滚的问题
学习spring分布式事务的时候,自己整了个demo,写test测试的时候发先事物没有回滚.此问题和分布式事务没关系.1.在service层引入@Transaction注解 使用 throw new ...
- 自定义镜像mycentos
1.编写 1).Hub默认CentOS镜像是什么情况 2).编写Dockerfile文件 2.构建 3.运行