展开

题目描述

很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治着整个星系。

某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球。这些星球通过特殊的以太隧道互相直接或间接地连接。

但好景不长,很快帝国又重新造出了他的超级武器。凭借这超级武器的力量,帝国开始有计划地摧毁反抗军占领的星球。由于星球的不断被摧毁,两个星球之间的通讯通道也开始不可靠起来。

现在,反抗军首领交给你一个任务:给出原来两个星球之间的以太隧道连通情况以及帝国打击的星球顺序,以尽量快的速度求出每一次打击之后反抗军占据的星球的连通块的个数。(如果两个星球可以通过现存的以太通道直接或间接地连通,则这两个星球在同一个连通块中)。

输入格式

输入文件第一行包含两个整数,n,mn,m,分别表示星球的数目和以太隧道的数目。星球用 0 \sim n-10∼n−1 的整数编号。

接下来的 mm 行,每行包括两个整数 x,yx,y,表示星球 xx 和星球 yy 之间有 “以太” 隧道,可以直接通讯。

接下来的一行为一个整数 kk ,表示将遭受攻击的星球的数目。

接下来的 kk 行,每行有一个整数,按照顺序列出了帝国军的攻击目标。这 kk 个数互不相同,且都在 00 到 n-1n−1 的范围内。

输出格式

第一行是开始时星球的连通块个数。接下来的 kk 行,每行一个整数,表示经过该次打击后现存星球的连通块个数。

输入输出样例

输入 #1复制

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
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]星球大战 [删边求连通块个数]的更多相关文章

  1. DFS:POJ1562-Oil Deposits(求连通块个数)

    Oil Deposits Time Limit: 1000MS Memory Limit: 10000K Description The GeoSurvComp geologic survey com ...

  2. 求连通块个数 - BFS、DFS、并查集实现

    本文基于leetcode的200.岛屿数量(题目

  3. P1197 [JSOI2008]星球大战(并查集判断连通块+正难则反)

    P1197 [JSOI2008]星球大战(并查集判断连通块+正难则反) 并查集本来就是连一对不同父亲的节点就的话连通块就少一个. 题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统 ...

  4. html5 canvas程序演示--P1197 [JSOI2008]星球大战

    html5 canvas程序演示--P1197 [JSOI2008]星球大战 <!doctype html> <html> <head> <meta char ...

  5. 洛谷P1197 [JSOI2008] 星球大战 [并查集]

    题目传送门 星球大战 题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系. 某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这 ...

  6. Luogu P1197 [JSOI2008]星球大战 By cellur925

    题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系. 某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过特殊的以太隧 ...

  7. P1197 [JSOI2008]星球大战[并查集+图论]

    题目来源:洛谷 题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治着整个星系. 某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球 ...

  8. P1197 [JSOI2008]星球大战

    题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过特殊的以太隧道 ...

  9. luogu P1197 [JSOI2008]星球大战

    题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过特殊的以太隧道 ...

随机推荐

  1. qq机器人 python实现 自动回复

    我以前写的代码我现在贴在了下面,下面的连接是我自己的博客,有问题希望大家提出来,一起进步...我以前试过,没啥问题.可以实现聊天. https://realwuxiong.github.io/blog ...

  2. Docker(二) 镜像

    简介 Docker镜像是什么? 它是一个只读的文件,就类似于我们安装操作系统时候所需要的那个iso光盘镜像,通过运行这个镜像来完成各种应用的部署. 这里的镜像就是一个能被docker运行起来的一个程序 ...

  3. java基础算法(一):最大子序列和问题的多种算法思路

    问题: /** * 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和,并顺序打印子序列. * 示例: * 输入: [-2,1,-3,4,-1,2,1 ...

  4. react FileReader读取TXT文件并保存 split切割字符串 map()分别渲染切割后的数组内的所有字符串

    //class my_fileReader( e ) {         console.log(e.target.files[0]);         const reader = new File ...

  5. asp.net core 2.2升到3.1遇到的问题小记

    趁着武汉疫情,在家研究原来2.2的框架升级到3.1的问题,在过程中遇到不少坑,好在放假有的是时间,一个一个解决,现做个简要记录,供大家参考.推荐认真看这篇文章 [https://docs.micros ...

  6. Flink安装及实例教程

    通过本教程我们将快速部署好flink在linux下的环境,并通过flink完成一个小demo的测试 一.准备阶段 flink压缩包下载(1.7.2): http://archive.apache.or ...

  7. python学习记录(八)

    0910--https://www.cnblogs.com/fnng/archive/2013/04/28/3048356.html Python异常 Python用异常对象(exception ob ...

  8. 基于 Google-S2 的地理相册服务实现及应用

    马蜂窝技术原创内容,更多干货请关注公众号:mfwtech 随着智能手机存储容量的增大,以及相册备份技术的普及,我们可以随时随地用手机影像记录生活,在手机中存储几千张甚至上万张照片已经是很常见的事情.但 ...

  9. [1天搞懂深度学习] 读书笔记 lecture I:Introduction of deep learning

    - 通常机器学习,目的是,找到一个函数,针对任何输入:语音,图片,文字,都能够自动输出正确的结果. - 而我们可以弄一个函数集合,这个集合针对同一个猫的图片的输入,可能有多种输出,比如猫,狗,猴子等, ...

  10. tomcat增加内存 JVM内存调优

    tomcat总是卡死,查看日志catalina.out 发现疯狂报错 如下,提示内存溢出 java.lang.OutOfMemoryError: Java heap space 此外常见的内存溢出有以 ...