Luogu P1197 [JSOI2008]星球大战 By cellur925
题目描述
很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系。
某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球。这些星球通过特殊的以太隧道互相直接或间接地连接。
但好景不长,很快帝国又重新造出了他的超级武器。凭借这超级武器的力量,帝国开始有计划地摧毁反抗军占领的星球。由于星球的不断被摧毁,两个星球之间的通讯通道也开始不可靠起来。
现在,反抗军首领交给你一个任务:给出原来两个星球之间的以太隧道连通情况以及帝国打击的星球顺序,以尽量快的速度求出每一次打击之后反抗军占据的星球的连通块的个数。(如果两个星球可以通过现存的以太通道直接或间接地连通,则这两个星球在同一个连通块中)。
输入输出格式
输入格式:
输入文件第一行包含两个整数, N( 1<=N<=2M ) 和 M ( 1<=M<=200,000 ),分别表示星球的数目和以太隧道的数目。星球用 0 ~ N-1 的整数编号。
接下来的 M 行,每行包括两个整数 X , Y ,其中(0<=X<>Y 表示星球 x 和星球 y之间有 “以太” 隧道,可以直接通讯。
接下来的一行为一个整数 ,表示将遭受攻击的星球的数目。
接下来的 k 行,每行有一个整数,按照顺序列出了帝国军的攻击目标。这 k个数互不相同,且都在 0到 n−1 的范围内。
输出格式:
第一行是开始时星球的连通块个数。接下来的 K 行,每行一个整数,表示经过该次打击后现存星球的连通块个数。
输入输出样例
8 13
0 1
1 6
6 5
5 0
0 6
1 2
2 3
3 4
4 5
7 1
7 2
7 6
3 6
5
1
6
3
5
7
1
1
1
2
3
3
说明
[JSOI2008]
删边不如加边--LVYOUYW。
当我们看到联通块,我们眼前一亮,脑海里闪过了并查集。可是我们如何维护每次删边的操作,看起来很复杂的样子。
我们不妨换个思路,先求最后所有边都被摧毁的情况,也就求出了最后一种情况的答案,再一点点的加边。因为我们会加边操作,不会删边操作啊!于是,这个离线算法就确定了。
具体操作:断边、连边,我们听起来是图论的样子,但在本题中实质就是在并查集中将他们合并/拆散。最开始的情况我们先用邻接表存好,而是否在集合的信息用并查集维护。
这样,当我们再读入需要断边的消息时,不断,而是默默记录。我们首先要意识到,加边联通块减少,断边联通块增多。这样我们就可以倒着遍历需要断的节点,并遍历与其相连的所有边。
code
#include<cstdio>
#include<algorithm> using namespace std; int n,m,cnt,tot,x,y,k,head[],ans[],f[],flag[],mark[];
struct node{
int to,next,from;
}edge[]; int getf(int x)
{
if(f[x]==x) return f[x];
return f[x]=getf(f[x]);
} void merge(int x,int y)
{
int pp=getf(x);
int qq=getf(y);
if(pp!=qq) f[qq]=pp;
} void add(int x,int y)
{
edge[++cnt].to=y;
edge[cnt].from=x;//不同于普通的邻接表,这里我们多维护了一个信息。
edge[cnt].next=head[x];
head[x]=cnt;
} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) f[i]=i,head[i]=-;
//初始化很重要!节点编号从0开始,head要设为-1
//另外注意初始化的位置(滑稽
for(int i=;i<=m;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
scanf("%d",&k);
for(int i=;i<=k;i++)
{
scanf("%d",&x);
flag[x]=;
mark[i]=x;
}
tot=n-k;//开始各点为一独立的联通块
for(int i=;i<=*m;i++)
{
if(!flag[edge[i].to]&&!flag[edge[i].from]&&getf(edge[i].to)!=getf(edge[i].from))
merge(edge[i].to,edge[i].from),tot--;
//每连一边,联通块便减少一点点
}
ans[k+]=tot;
for(int i=k;i>=;i--)
{
tot++;int p=mark[i];flag[p]=;
//当前未连时的点是一个独立的联通块
for(int j=head[p];j!=-;j=edge[j].next)
{//head意义改变,这里也就变了,注意!
if(!flag[edge[j].to]&&getf(edge[j].to)!=getf(p))
tot--,merge(edge[j].to,p);
}
ans[i]=tot;
}
for(int i=;i<=k+;i++) printf("%d\n",ans[i]);
return ;
}
附:并查集求联通块个数
https://blog.csdn.net/rcy_zhu/article/details/77622043
Luogu P1197 [JSOI2008]星球大战 By cellur925的更多相关文章
- luogu P1197 [JSOI2008]星球大战
题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过特殊的以太隧道 ...
- [Luogu 1197] JSOI2008 星球大战
[Luogu 1197] JSOI2008 星球大战 我算是真的沦为联赛选手了. 并查集裸题. 比较麻烦的是删点. 但是从后往前加点就好操作很多. 所以考虑离线,先存图,然后没被删的点之间,有边就合并 ...
- html5 canvas程序演示--P1197 [JSOI2008]星球大战
html5 canvas程序演示--P1197 [JSOI2008]星球大战 <!doctype html> <html> <head> <meta char ...
- P1197 [JSOI2008]星球大战(并查集判断连通块+正难则反)
P1197 [JSOI2008]星球大战(并查集判断连通块+正难则反) 并查集本来就是连一对不同父亲的节点就的话连通块就少一个. 题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统 ...
- 洛谷P1197 [JSOI2008] 星球大战 [并查集]
题目传送门 星球大战 题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系. 某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这 ...
- P1197 [JSOI2008]星球大战——链式前向星+并查集
https://www.luogu.org/problem/P1197 这道题算是关闭农场的加强版吧,数据有点大,矩阵存不下: 也是记录删点操作,从后往前加边: 先将每个点都算成一个连通块,然后每连一 ...
- 洛谷 P1197 [JSOI2008]星球大战——并查集
先上一波题目 https://www.luogu.org/problem/P1197 很明显删除的操作并不好处理 那么我们可以考虑把删边变成加边 只需要一波时间倒流就可以解决拉 储存删边顺序倒过来加边 ...
- P1197 [JSOI2008]星球大战
题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过特殊的以太隧道 ...
- P1197 [JSOI2008]星球大战[并查集+图论]
题目来源:洛谷 题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治着整个星系. 某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球 ...
随机推荐
- BZOJ——2697: 特技飞行
http://www.lydsy.com/JudgeOnline/problem.php?id=2697 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: ...
- SVN 更新后Tomcat 启动时出现问题
更新了svn后,启动本地的tomcat容器发现启动不了, 检查后发现是配置文件配置出现问题,因为我们的该项目 配置有tomcat与weblogic两种 , 而在我的web.xml中 默认配置的serv ...
- C语言取整方法总结
C语言有下面几种取整方法: 1. 直接赋值给整数变量 int i = 3.5; 或 i = (int) 3.5; 这样的方法採用的是舍去小数部分. 2.整数除法运算符' / '取整 ' / ...
- Puppet基于Master/Agent模式实现LNMP平台部署
前言 随着IT行业的迅猛发展,传统的运维方式靠大量人力比较吃力,运维人员面对日益增长的服务器和运维工作,不得不把很多重复的.繁琐的工作利用自动化处理.前期我们介绍了运维自动化工具ansible的简单应 ...
- 2003 -Can't connection to mysql server on | navicat for mysql Access denied for user 'root'@''ip'(using password :yes)
用本机windows上的Navicat for mysql链接虚拟机Linux的mysql数据库时,第一次连接的时候报的错误是 2003 -Can't connection to mysql serv ...
- VB6 如何自定义代码字体和支持鼠标滚轮
1 点击工具-选项-编辑器格式,把代码改成需要的字体和大小.(一般微软雅黑,16号字体比较好) 2 从以下网站下载VB6增强工具,可以支持鼠标滚轮代替右侧滚动条查看代码,按F3还可以切换代码窗口和 ...
- web 开发之js---ajax 异步处理
本文介绍了如何创建能够适应不同浏览器的XMLHttpRequest实例,建立和发送请求,并响应服务器.您将开始接触最基本和基础性的有关Ajax的全部对象和编程方法:XMLHttpRequest对象.该 ...
- GridView根据一列自动计算(转载)
<%@ Page Language="C#" %> <%@ Import Namespace="System.Xml" %> <! ...
- unix2dos/dos2unix
dos2unix命令用来将DOS格式的文本文件转换成UNIX格式的(DOS/MAC to UNIX text file format converter).DOS下的文本文件是以\r\n作为断行标志的 ...
- string string.h cstring 区别
c++中 string与string.h 的作用和区别 #include <string.h> void main() { string aaa= "a ...