博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
P1197 [JSOI2008]星球大战
阅读量:5969 次
发布时间:2019-06-19

本文共 1227 字,大约阅读时间需要 4 分钟。

并查集维护集合


这道题code写起来很容易

但有很多启示

这道题需要逆序做

为什么呢?

对于路径压缩的并查集来说,如果合并了。那么想要在分开是很难的。

而且这道题要求每步输出。但是!! 这道题是先给操作,再统一输出!! 我们就可以离线做

那么我们就可以逆序做

先处理最后的状态,然后倒着合并。这样的话,就可以很快的跑出来了

对于合并容易,分开难得数据结构。在要求支持分开的离线操作题中。我们可以将分开换做合并。 倒着做

#include
#include
#include
using namespace std;int f[401000];int find(int x){ if(f[x]==x) return x; return f[x]=find(f[x]);}struct node{ int point; int nxt;};node l[401000];int head[401000],tail;int in[401000][2];void add(int x,int y){ l[++tail].point=y; l[tail].nxt=head[x]; head[x]=tail;}int able[400010];bool use[400010];int ans[400010];int main(){ int n,m,k; scanf("%d%d",&n,&m); for(int i=0;i
=1;i--) { ans[i]=tot; for(int need=head[able[i]];need;need=l[need].nxt) { int f1=find(able[i]),f2=find(l[need].point); if(f1!=f2&&!use[l[need].point]) { tot-=1; f[f1]=f2; } } tot+=1;//因为第一次合并时,集合数并不会减少,所以这里将tot补回来 use[able[i]]=false; } ans[0]=tot; for(int i=0;i<=k;i++) printf("%d\n",ans[i]);}/*5 70 10 20 42 32 11 33 13241*/

转载于:https://www.cnblogs.com/Lance1ot/p/8642947.html

你可能感兴趣的文章
.Net Core下使用 RSA
查看>>
python 数据库中文乱码 Excel
查看>>
利用console控制台调试php代码
查看>>
递归算法,如何把list中父子类对象递归成树
查看>>
jsf初学解决GlassFish Server 无法启动
查看>>
hdu 1050 (preinitilization or postcleansing, std::fill) ...
查看>>
Form各键盘触发子所对应的“按键”
查看>>
【java IO】使用Java输入输出流 读取txt文件内数据,进行拼接后写入到另一个文件中...
查看>>
Linux系统下安装rz/sz命令及使用说明
查看>>
第一次模拟面试
查看>>
window.showModalDialog
查看>>
Pycharm选择pyenv安装的Python版本
查看>>
?Sized 和 Sized
查看>>
Java中如何防止内存泄漏的发生
查看>>
Java中Int转byte分析
查看>>
滑动窗口最大值的golang实现
查看>>
初学Phreeze 3
查看>>
会计的思考(17):还原会计报表的企业个性之一
查看>>
java对象初始化顺序的简单验证
查看>>
[CF452E]Three strings
查看>>