P1197 [JSOI2008]星球大战 [删边求连通块个数]
题目描述
很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治着整个星系。
某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球。这些星球通过特殊的以太隧道互相直接或间接地连接。
但好景不长,很快帝国又重新造出了他的超级武器。凭借这超级武器的力量,帝国开始有计划地摧毁反抗军占领的星球。由于星球的不断被摧毁,两个星球之间的通讯通道也开始不可靠起来。
现在,反抗军首领交给你一个任务:给出原来两个星球之间的以太隧道连通情况以及帝国打击的星球顺序,以尽量快的速度求出每一次打击之后反抗军占据的星球的连通块的个数。(如果两个星球可以通过现存的以太通道直接或间接地连通,则这两个星球在同一个连通块中)。
输入格式
输入文件第一行包含两个整数,n,mn,m,分别表示星球的数目和以太隧道的数目。星球用 0 \sim n-10∼n−1 的整数编号。
接下来的 mm 行,每行包括两个整数 x,yx,y,表示星球 xx 和星球 yy 之间有 “以太” 隧道,可以直接通讯。
接下来的一行为一个整数 kk ,表示将遭受攻击的星球的数目。
接下来的 kk 行,每行有一个整数,按照顺序列出了帝国军的攻击目标。这 kk 个数互不相同,且都在 00 到 n-1n−1 的范围内。
输出格式
第一行是开始时星球的连通块个数。接下来的 kk 行,每行一个整数,表示经过该次打击后现存星球的连通块个数。
输入输出样例
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

思路
对于删边求连通块个数问题, 就我遇到的来说,一般可以考虑暴搜,并查集和tarjan来做.
对于此题来说, 显然用并查集做更简单, 考虑用并查集实现.
由于并查集写删边的码量很大很复杂, 但是建边很容易, 所以考虑反向处理.
首先, 令所有点都是单独的连通块, 因为炸掉了就不能参与构成连通块了, 所以先处理出剩下了多少可以操作的连通块.
令最终态就是此时的连通块个数, 接着反向加点连边.
每加上一个点, 连通块的个数肯定就要 + 1 , 然后遍历炸点之前它可以连的边, 如果连上一个连通块, 那么对应的此时连通块个数就要 - 1 ;
最后就可以处理出每个点炸点前的连通块数量, 反向输出即可.
CODE
#include <bits/stdc++.h>
#define dbg(x) cout << #x << "=" << x << endl
#define eps 1e-8
#define pi acos(-1.0) using namespace std;
typedef long long LL; template<class T>inline void read(T &res)
{
char c;T flag=;
while((c=getchar())<''||c>'')if(c=='-')flag=-;res=c-'';
while((c=getchar())>=''&&c<='')res=res*+c-'';res*=flag;
} namespace _buff {
const size_t BUFF = << ;
char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
char getc() {
if (ib == ie) {
ib = ibuf;
ie = ibuf + fread(ibuf, , BUFF, stdin);
}
return ib == ie ? - : *ib++;
}
} int qread() {
using namespace _buff;
int ret = ;
bool pos = true;
char c = getc();
for (; (c < '' || c > '') && c != '-'; c = getc()) {
assert(~c);
}
if (c == '-') {
pos = false;
c = getc();
}
for (; c >= '' && c <= ''; c = getc()) {
ret = (ret << ) + (ret << ) + (c ^ );
}
return pos ? ret : -ret;
} const int maxn = 2e5 + ; int cnt, head[maxn << ], edge[maxn << ], nxt[maxn << ], from[maxn << ];
bool vis[maxn << ];
int a[maxn << ], ans[maxn << ],fa[maxn << ];
int tot,n,m,x,y,k; void BuildGraph(int u, int v) {
cnt++;
edge[cnt] = v;
from[cnt] = u;
nxt[cnt] = head[u];
head[u] = cnt;
} int fid(int x) {
return x == fa[x] ? x : fa[x] = fid(fa[x]);
} int main()
{
scanf("%d %d",&n, &m);
for ( int i = ; i <= m; ++i ) {
int u, v;
scanf("%d %d",&u, &v);
BuildGraph(u, v);
BuildGraph(v, u);
}
scanf("%d",&k);
for ( int i = ; i <= k; ++i ) {
int x;
scanf("%d",&x);
vis[x] = ;
a[i] = x;
}
for ( int i = ; i <= n; ++i ) {
fa[i] = i;
}
tot = n - k;
for ( int i = ; i <= * m; ++i ) {
if(!vis[from[i]] && !vis[edge[i]]) {
if(fa[fid(from[i])] != fa[fid(edge[i])]) {
tot--;
fa[fid(from[i])] = fa[fid(edge[i])];
}
}
}
ans[k+] = tot;
for ( int i = k; i >= ; --i ) {
int x = a[i];
vis[x] = ;
tot++;
for ( int j = head[x]; j; j = nxt[j] ) {
if(vis[edge[j]] == && fa[fid(x)] != fa[fid(edge[j])]) {
tot--;
fa[fid(x)] = fa[fid(edge[j])];
}
}
ans[i] = tot;
}
for ( int i = ; i <= k+; ++i ) {
printf("%d\n",ans[i]);
}
return ;
}
P1197 [JSOI2008]星球大战 [删边求连通块个数]的更多相关文章
- DFS:POJ1562-Oil Deposits(求连通块个数)
Oil Deposits Time Limit: 1000MS Memory Limit: 10000K Description The GeoSurvComp geologic survey com ...
- 求连通块个数 - BFS、DFS、并查集实现
本文基于leetcode的200.岛屿数量(题目
- P1197 [JSOI2008]星球大战(并查集判断连通块+正难则反)
P1197 [JSOI2008]星球大战(并查集判断连通块+正难则反) 并查集本来就是连一对不同父亲的节点就的话连通块就少一个. 题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统 ...
- html5 canvas程序演示--P1197 [JSOI2008]星球大战
html5 canvas程序演示--P1197 [JSOI2008]星球大战 <!doctype html> <html> <head> <meta char ...
- 洛谷P1197 [JSOI2008] 星球大战 [并查集]
题目传送门 星球大战 题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系. 某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这 ...
- Luogu P1197 [JSOI2008]星球大战 By cellur925
题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系. 某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过特殊的以太隧 ...
- P1197 [JSOI2008]星球大战[并查集+图论]
题目来源:洛谷 题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治着整个星系. 某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球 ...
- P1197 [JSOI2008]星球大战
题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过特殊的以太隧道 ...
- luogu P1197 [JSOI2008]星球大战
题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过特殊的以太隧道 ...
随机推荐
- Linux下的expect
expect简介 expect是一款自动化的脚本解释型的工具. expect基于tcl脚本,expect脚本的运行需要tcl的支持. expect对一些需要交互输入的命令很有帮助,比如ssh ftp ...
- learn more ,study less(二):整体性学习技术(下)
随意信息的处理 随意信息,或者内容太多.太复杂的信息,都不容易理解,它们需要不同的技术.假 如你发现联想法不能帮助你理解材料,或者需要花费的时间太长,这时候处理随意信息的方 法就很适合了. 这些处理随 ...
- 转载: Java虚拟机:运行时内存数据区域、对象内存分配与访问
转载: https://blog.csdn.net/a745233700/article/details/80291694 (虽然大部分内容都其实是深入理解jvm虚拟机这本书里的,不过整理的很牛逼 ...
- docker挂载war包到tomcat容器中的注意点和坑
刚开始用docker,难免会遇到很多坑,这里分享一下: 一 挂载最好挂载目录 我刚开始挂载war包,结果发现容器里把挂载的war包当成目录了 二 本地路径必须是绝对路径,否则不管用 三 容器中使用vi ...
- hash模式与history模式
随着 ajax 的使用越来越广泛,前端的页面逻辑开始变得越来越复杂,特别是spa的兴起,前端路由系统随之开始流行. 从用户的角度看,前端路由主要实现了两个功能(使用ajax更新页面状态的情况下): 记 ...
- spring中创建bean对象的三种方式以及作用范围
时间:2020/02/02 一.在spring的xml配置文件中创建bean对象的三种方式: 1.使用默认构造函数创建.在spring的配置文件中使用bean标签,配以id和class属性之后,且没有 ...
- 16、ISDN
ISDN:综合业务数据网 分类:1.宽带ISDN:基本上被淘汰2.窄带ISDN:用于备份链路,速率比较低 ISDN的起源和优点 ISDN能够提供声音.视频.数据等传输业务 ISDN的两种服务方式ISD ...
- Spacemacs安装
Spacemacs官网 为什么选择Spacemacs Spacemacs是一个已经配好的Emacs和Vim,正如官网所说的The best editor is neither Emacs nor Vi ...
- python库之matplotlib学习---关于坐标轴
首先定·定义x, y创建一个figure import numpy as np import matplotlib.pyplot as plt x = np.linspace(-1, 1, 10) y ...
- 使用bisect库实现二分查找
手动实现 假如有一个有序表nums,怎么样在nums里找到某个值的位置呢?没错,就是nums.index(k),哈哈哈哈哈哈哈-- 假如nums很长很长,那就要祭出二分查找了 def binary_s ...