P1197 [JSOI2008]星球大战[并查集+图论]
题目来源:洛谷
题目描述
很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治着整个星系。
某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球。这些星球通过特殊的以太隧道互相直接或间接地连接。
但好景不长,很快帝国又重新造出了他的超级武器。凭借这超级武器的力量,帝国开始有计划地摧毁反抗军占领的星球。由于星球的不断被摧毁,两个星球之间的通讯通道也开始不可靠起来。
现在,反抗军首领交给你一个任务:给出原来两个星球之间的以太隧道连通情况以及帝国打击的星球顺序,以尽量快的速度求出每一次打击之后反抗军占据的星球的连通块的个数。(如果两个星球可以通过现存的以太通道直接或间接地连通,则这两个星球在同一个连通块中)。
输入输出格式
输入格式:
输入文件第一行包含两个整数,N (1<=N<=2M) 和 M (1<=M<=200,000),分别表示星球的数目和以太隧道的数目。星球用 0 ~ N-1 的整数编号。
接下来的 M 行,每行包括两个整数 X, Y,其中( 0<=X<>Y 表示星球 xx 和星球 yy 之间有 “以太” 隧道,可以直接通讯。
接下来的一行为一个整数 k ,表示将遭受攻击的星球的数目。
接下来的 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]
这道题十分考验代码力和思维,需要对并查集和图论理解深入。
解析:
看到这题,我们如果按照题目意思理解,也可以很容易得到思路,只要建一个并查集,维护联通块就可以了。
但是根据题意,我们要从中删点,并在每次删完点之后统计联通块数量。
这就很令人头大了,我们知道,并查集并查集,合并容易删除难啊,这可怎么办呐?
没错,你可能已经想到了,既然合并比删除容易,那我们不妨倒转思路,逆向求解。
我们把题目改一下,姑且就叫它“反抗军重建计划”好了qwq:
很久以前,在一个遥远的星系,反抗军为了弥补之前帝国军队攻击的损失,开始了重建计划。
现在,反抗军首领交给你一个任务:给出将要重建的星球和重建计划中所有星球与其它星球之间的以太隧道,以尽量快的速度求出每重建完一个星球之后反抗军占据的星球的连通块的个数。(如果两个星球可以通过现存的以太通道直接或间接地连通,则这两个星球在同一个连通块中)。
嘿嘿,这是不是简单多了?而且跟原题正好反过来,求得的解也正好逆序。
思路还是差不多,每次重建星球后,将该星球与计划中要联通的星球合并入并查集中,这道题就完成了。
但是这里要提一个点,关于邻接表。在本题中,我们当然可以把所有星球看做一个无向图,并用邻接表储存。
但是实际上我们可以这样理解:邻接表中的表头可以用于表示某一个将要重建的星球与其它星球的联通关系。
参考代码:
//反抗军重建计划qwq
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<cstring>
#define N 100010
using namespace std;
//邻接表存图
struct node{
int next,ver,from;
}g[N<<];
int n,m,k,tot;
int head[N<<],ans[N<<],fa[N<<],b[N<<];
bool v[N<<];//是否需要重建
void add(int x,int y)
{
g[++tot].ver=y,g[tot].from=x;
g[tot].next=head[x],head[x]=tot;
}
int get(int x)
{
if(fa[x]==x) return x;
return fa[x]=get(fa[x]);
}
void merge(int x,int y)
{
x=get(x),y=get(y);
if(x!=y) fa[x]=y;
}
int main()
{
memset(v,,sizeof(v));
memset(b,,sizeof(b));
scanf("%d%d",&n,&m); for(int i=;i<n;i++) fa[i]=i;//初始化 for(int i=;i<=m;i++){
int x,y;
scanf("%d%d",&x,&y);
add(x,y),add(y,x);
}
scanf("%d",&k);
//需要重建的星球
for(int i=;i<=k;i++){
scanf("%d",&b[i]);
v[b[i]]=;//记录一下该星球需要重建
}
int cnt=n-k;
//还没重建,我们就先联通起来没被摧毁的星球
//如果两个星球都存在,也就是都不用重建时,合并
for(int i=;i<=*m;i++){
if(!v[g[i].ver]&&!v[g[i].from]&&get(g[i].from)!=get(g[i].ver)){
cnt--;merge(g[i].from,g[i].ver);
}
}
//从后往前将摧毁的星球建回去
ans[k+]=cnt;
for(int i=k;i>=;i--){
//统计联通块个数
cnt++;v[b[i]]=;
for(int j=head[b[i]];j;j=g[j].next){
if(!v[g[j].ver]&&get(g[j].from)!=get(g[j].ver)){
cnt--;merge(b[i],g[j].ver);
}
}
ans[i]=cnt;
}
for(int i=;i<=k+;i++) printf("%d\n",ans[i]);
return ;
}
P1197 [JSOI2008]星球大战[并查集+图论]的更多相关文章
- 洛谷P1197 [JSOI2008] 星球大战 [并查集]
题目传送门 星球大战 题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系. 某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这 ...
- P1197 [JSOI2008]星球大战 并查集 反向
题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治着整个星系. 某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过特殊的以太隧 ...
- 洛谷 P1197 [JSOI2008]星球大战——并查集
先上一波题目 https://www.luogu.org/problem/P1197 很明显删除的操作并不好处理 那么我们可以考虑把删边变成加边 只需要一波时间倒流就可以解决拉 储存删边顺序倒过来加边 ...
- JSOI2008 星球大战 [并查集]
题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系. 某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过特殊的以太隧 ...
- [bzoj1015][JSOI2008]星球大战——并查集+离线处理
题解 给定一张图,支持删点和询问连通块个数 按操作顺序处理的话要在删除点的同时维护图的形态(即图具体的连边情况),这是几乎不可做的 我们发现,这道题可以先读入操作,把没删的点的边先连上,然后再倒序处理 ...
- P1197 [JSOI2008]星球大战(并查集判断连通块+正难则反)
P1197 [JSOI2008]星球大战(并查集判断连通块+正难则反) 并查集本来就是连一对不同父亲的节点就的话连通块就少一个. 题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统 ...
- html5 canvas程序演示--P1197 [JSOI2008]星球大战
html5 canvas程序演示--P1197 [JSOI2008]星球大战 <!doctype html> <html> <head> <meta char ...
- Bzoj1015/洛谷P1197 [JSOI2008]星球大战(并查集)
题面 Bzoj 洛谷 题解 考虑离线做法,逆序处理,一个一个星球的加入.用并查集维护一下连通性就好了. 具体来说,先将被消灭的星球储存下来,先将没有被消灭的星球用并查集并在一起,这样做可以路径压缩,然 ...
- 【反向并查集、联通图】P1197 [JSOI2008]星球大战
题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治着整个星系. 某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过特殊的以太隧 ...
随机推荐
- 【Spring Boot学习之四】Spring Boot事务管理
环境 eclipse 4.7 jdk 1.8 Spring Boot 1.5.2 一.springboot整合事务事务分类:编程事务.声明事务(XML.注解),推荐使用注解方式,springboot默 ...
- mybatis异常集锦
[Mybatis]报错:Malformed OGNL expression: name!= null and name != ' ' [Mybatis]报错:Malformed OGNL expres ...
- netcore 步骤
1.创建工程目录 d:\project 2.进入目录,创建解决方案 dotnet new sln 3.确定开发版本 dotnet --list-sdks //列出sdk版本 dotnet new gl ...
- VMware版本为15安装win7旗舰版不能成功安装VMware tools
VMware版本为15安装win7旗舰版不能成功安装VMware tools 出现的问题: 一直报错说需要系统更新到SP1系统,到网上找了很多升级方式,都未果 直接通过Windows Update,未 ...
- Django框架(十二)-- 中间件、CSRF跨站请求伪造
中间件 一.什么是中间件 请求的时候需要先经过中间件才能到达django后端(urls,views,templates,models) 响应的时候也需要经过中间件才能到达web服务网关接口 djang ...
- 深度学习-CNN+RNN笔记
以下叙述只是简单的叙述,CNN+RNN(LSTM,GRU)的应用相关文章还很多,而且研究的方向不仅仅是下文提到的1. CNN 特征提取,用于RNN语句生成图片标注.2. RNN特征提取用于CNN内容分 ...
- U9期间在手量控制
1.路径 库存管理->参数控制 2.设置节点 期间在手量控制时机 :单据实时控制.日关账控制.不控制 3.实现效果
- javaweb之添加学生信息
1登录账号:要求由6到12位字母.数字.下划线组成,只有字母可以开头:(1分) 2登录密码:要求显示“• ”或“*”表示输入位数,密码要求八位以上字母.数字组成.(1分) 3性别:要求用单选框或下拉框 ...
- java转换编码报错java.lang.IllegalArgumentException: URLDecoder: Illegal hex characters in escape (%) pattern
Exception in thread "main" java.lang.IllegalArgumentException: URLDecoder: Illegal hex cha ...
- Tomcat组件梳理--Catalina
Tomcat组件梳理--Catalina 1.定义和功能 Catalina是Tomcat的核心组件,是Servlet容器,Catalina包含了所有的容器组件,其他模块均为Catalina提供支撑.通 ...