ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[JSOI2008]星球大战

2019-07-03 19:40:49  阅读:242  来源: 互联网

标签:连通 星球大战 以太 int JSOI2008 bj 400005 星球


题目描述

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

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

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

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

输入输出格式

输入格式:

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

接下来的 M 行,每行包括两个整数 X ,Y,其中( 0 < = X <> Y 表示星球 x 和星球 y 之间有 “以太” 隧道,可以直接通讯。

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

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

输出格式:

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

输入输出样例

输入样例#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
3

分析:
本题显然是一道求连通块题目,那么不难想到并查集,而本题之所以虽然是普通并查集但却是蓝题在于不停地修改并查集中的数据以及求个数。但事实上只需要开数组记录即可。

CODE:
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 int f[400005];
 7 int u[400005];
 8 bool bj[400005];
 9 int next[400005],to[400005],head[400005];
10 int n,m,k,tot;
11 int ans[400005],now;
12 void add(int u,int v){
13     to[++tot]=v;
14     next[tot]=head[u];
15     head[u]=tot;
16 }
17 int find(int k){
18     if(f[k]==k) return k;
19     return f[k]=find(f[k]);
20 }
21 void merge(int x,int y){
22     int A=find(f[x]);
23     int B=find(f[y]);
24     if (A!=B) now--,f[B]=A;
25     return ;
26 }
27 int main(){
28     memset(bj,true,sizeof(bj));
29     cin>>n>>m;
30     for (int i=0;i<n;i++) f[i]=i;
31     for (int i=1;i<=m;i++){
32         int x,y;
33         scanf ("%d%d",&x,&y);
34         add(x,y);
35         add(y,x);
36     }
37     cin>>k;
38     for (int i=1;i<=k;i++)
39     scanf ("%d",&u[i]),bj[u[i]]=false;
40     now=n-k;
41     for (int i=1;i<=n;i++){
42         for (int j=head[i];j;j=next[j]){
43             if (bj[i]&&bj[to[j]]) merge(i,to[j]);
44         }
45     }
46     ans[k]=now;
47     for (int i=k;i>=1;i--){
48         now++;
49         bj[u[i]]=true;
50         for (int j=head[u[i]];j;j=next[j])
51         if (bj[to[j]])
52         merge(u[i],to[j]);
53         ans[i-1]=now;
54     }
55     for (int i=0;i<=k;i++)
56     printf ("%d\n",ans[i]);
57     //system("pause");
58     return 0;
59 }

 

 
 

标签:连通,星球大战,以太,int,JSOI2008,bj,400005,星球
来源: https://www.cnblogs.com/kanchuang/p/11128537.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有