题目描述

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

但好景不长,很快帝国又重新造出了他的超级武器。凭借这超级武器的力量,帝国开始有计划地摧毁反抗军占领的星球。由于星球的不断被摧毁,两个星球之间的通讯通道也开始不可靠起来。现在,反抗军首领交给你一个任务:给出原来两个星球之间的以太隧道连通情况以及帝国打击的星球顺序,以尽量快的速度求出每一次打击之后反抗军占据的星球的连通快的个数。(如果两个星球可以通过现存的以太通道直接或间接地连通,则这两个星球在同一个连通块中)。

输入输出格式

输入格式:

输入文件第一行包含两个整数,N (1 <= N <= 2M) 和M (1 <= M <= 200,000),分别表示星球的数目和以太隧道的数目。星球用0~N-1的整数编号。

接下来的M行,每行包括两个整数X, Y,其中(0<=X<>Y<N),表示星球X和星球Y之间有以太隧道。注意所有的以太隧道都是双向的。

接下来一行是一个整数K,表示帝国计划打击的星球个数。

接下来的K行每行一个整数X,满足0<=X<N,表示帝国计划打击的星球编号。帝国总是按输入的顺序依次摧毁星球的。

输出格式:

输出文件的第一行是开始时星球的连通块个数。

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

***************************************************************

由于并查集难以进行删除的操作(要不怎么叫做并查集),我们便可以逆向思考一下,先求出所有星球都打击完之后

的连通块个数,然后一个个把打击的星球加上,同时再次统计连通块的个数。

以上是思想,但是在代码实现时,我认为有几点需要注意的(尤其是我这种==的代码)

1.对以太隧道进行储存时,可以借鉴图论中邻接表的方法,找出和一个点相连的所有隧道

2.统计连通块的个数可以用一个计数器,每次加入一个新点计数器自加,每次合并两个连通块计数器自减。

3.讲父节点初始值设为-1,加入这个节点时将其改为本身,这样比较好判断哪些点尚未加入

END

************************

#include<cstdio>
#include<algorithm>
#define maxn 200001
using namespace std;
struct Edge
{
int num;
int next;
}edge[maxn * ];
int head[maxn * ];
int note[maxn];
int shuru[maxn];
bool visited[maxn * ];
int father[maxn * ];
int top = ;
int n,m,cns,k = ;
int read()
{
int num = ;
char c = getchar();
int f = ;
while(c < ''||c > '')
{
if(c == '-')f = -;
c = getchar();
}
while(c >= '' && c <= '')
{
num *= ;
num += c - '';
c = getchar();
}
return num * f;
}
int find(int x)
{
return father[x] == x ? x:father[x] = find(father[x]);
}
void unionn(int vi,int vj)
{
father[find(vj)] = find(vi);
}
void push(int vi,int vj)
{
top ++;
edge[top].num = vj;
edge[top].next = head[vi];
head[vi] = top;
}
void Pang(int x)
{
father[x] = x; cns++;
for(int i = head[x];i != -;i = edge[i].next)
{
int j = edge[i].num;
if(father[j] != -)
{
if(find(j) != find(x))
{
unionn(x,j);
cns--;
}
}
}
}
int main()
{
n = read();
m = read();
for(int i = ;i < n;i ++)
{
father[i] = -;
head[i] = -;
}
for(int i = ;i <= m;i ++)
{
int vi = read(),vj = read();
push(vi,vj);
push(vj,vi);
}
k = read();
for(int i = ;i <= k;i ++)
{
shuru[i] = read();
visited[shuru[i]] = true;
}
for(int i = ;i < n;i ++)
{
if(!visited[i])
{
Pang(i);
}
}
note[]=cns;
for(int i = k;i >= ;i --)
{
Pang(shuru[i]);
note[i] = cns;
}
for(int i = ;i <= k;i ++)
{
printf("%d\n",note[i]);
}
printf("%d",note[]);
return ;
}

洛谷 P1197 [JSOI2008]星球大战的更多相关文章

  1. Bzoj1015/洛谷P1197 [JSOI2008]星球大战(并查集)

    题面 Bzoj 洛谷 题解 考虑离线做法,逆序处理,一个一个星球的加入.用并查集维护一下连通性就好了. 具体来说,先将被消灭的星球储存下来,先将没有被消灭的星球用并查集并在一起,这样做可以路径压缩,然 ...

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

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

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

    先上一波题目 https://www.luogu.org/problem/P1197 很明显删除的操作并不好处理 那么我们可以考虑把删边变成加边 只需要一波时间倒流就可以解决拉 储存删边顺序倒过来加边 ...

  4. 洛谷P1197 [JSOI2008]星球大战

    题目 由于题目不要求强制在线,所以可以离线. 而离线的话就会带来许多便利,所以我们可以先处理出全部打击后的图,通过并查集来判断是否连通. 然后再从后往前枚举,得出答案 #include <bit ...

  5. BZOJ1015或洛谷1197 [JSOI2008]星球大战

    BZOJ原题链接 洛谷原题链接 发现正着想毫无思路,所以我们可以考虑倒着思考,把摧毁变成建造. 这样很容易想到用并查集来维护连通块,问题也变的很简单了. 建原图,先遍历一遍所有边,若某条边的两端点未被 ...

  6. 洛谷 1197 [JSOI2008]星球大战

    [题解] 把询问离线,倒着加点,并查集维护连通性即可. #include<cstdio> #include<cstring> #include<algorithm> ...

  7. 并查集【洛谷P1197】 [JSOI2008]星球大战

    P1197 [JSOI2008]星球大战 题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治着整个星系. 某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系 ...

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

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

  9. 洛谷 P1198 [JSOI2008]最大数

    洛谷 P1198 [JSOI2008]最大数 题目描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值. ...

随机推荐

  1. 使用自己的域名解析cnblogs博客(CSDN也可以)

    本文主要介绍怎样使用自己购买的域名指向cnblogs博客 通常来说技术人员都会创建个自己的技术博客,总结下工作中的问题,经验等等,不过某些博客的访问链接的确是不太容易记忆或者输入,对我们分享造成一定的 ...

  2. 广播中receiver配置需要注意data的配置

    1.sd卡的转载和卸载 这个需要配置好android:scheme=“file” 要不然是检测不到的 2.在安装应用或者卸载应用都要有一个约束,要不然是不会执行的.而这个约束条件为package. 但 ...

  3. 【HDU5421】Victor and String(回文树)

    [HDU5421]Victor and String(回文树) 题面 Vjudge 大意: 你需要支持以下操作: 动态在前端插入一个字符 动态在后端插入一个字符 回答当前本质不同的回文串个数 回答当前 ...

  4. HDU1081 最大字段和 压缩数组(单调队列优化)

    最大字段和题型,推荐做题顺序: HDU1003 HDU1024 HDU1081  ZOJ2975 ZOJ2067 #include<cstdio> #include<cstdlib& ...

  5. C# 处理DateTime算法,取某月第1天及最后一天

    代码如下所示: /// <summary> /// 取得某月的第一天 /// </summary> /// <param name="datetime" ...

  6. Knight Tournament 合并区间

    Hooray! Berl II, the king of Berland is making a knight tournament. The king has already sent the me ...

  7. Sort An Unsorted Stack

    Given a stack of integers, sort it in ascending order using another temporary stack. Examples: Input ...

  8. .hex文件和.bin文件的区别

    博客转之于:  http://mini.eastday.com/a/160627003502858.html HEX文件和BIN文件是我们经常碰到的2种文件格式.下面简单介绍一下这2种文件格式的区别: ...

  9. log4net保存到数据库系列二:独立配置文件中配置log4net

    园子里面有很多关于log4net保存到数据库的帖子,但是要动手操作还是比较不易,从头开始学习log4net数据库日志一.WebConfig中配置log4net 一.WebConfig中配置log4ne ...

  10. 怎样在两小时内搞定 OpenStack 部署?(转)

    怎样在两小时内搞定 OpenStack 部署? OpenStack的安装是一个难题,组件众多,非常麻烦.如果手工部署OpenStack,可能需要好几天,使用RDO,就是几个命令,再加一两个小时的等待. ...