1015: [JSOI2008]星球大战starwar

Description

  很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系。某一天,凭着一个偶然的
机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球。这些星球通过特殊的以太隧道互相直
接或间接地连接。 但好景不长,很快帝国又重新造出了他的超级武器。凭借这超级武器的力量,帝国开始有计划
地摧毁反抗军占领的星球。由于星球的不断被摧毁,两个星球之间的通讯通道也开始不可靠起来。现在,反抗军首
领交给你一个任务:给出原来两个星球之间的以太隧道连通情况以及帝国打击的星球顺序,以尽量快的速度求出每
一次打击之后反抗军占据的星球的连通快的个数。(如果两个星球可以通过现存的以太通道直接或间接地连通,则
这两个星球在同一个连通块中)。

Input

  输入文件第一行包含两个整数,N (1  < =  N  < =  2M) 和M (1  < =  M  < =  200,000),分别表示星球的
数目和以太隧道的数目。星球用 0 ~ N-1的整数编号。接下来的M行,每行包括两个整数X, Y,其中(0 < = X <> 
Y 表示星球x和星球y之间有“以太”隧道,可以直接通讯。接下来的一行为一个整数k,表示将遭受攻击的星球的
数目。接下来的k行,每行有一个整数,按照顺序列出了帝国军的攻击目标。这k个数互不相同,且都在0到n-1的范
围内。

Output

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

Sample Input

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

Sample Output

1
1
1
2
3
3
 
 
这道题的思路就是我们从后往前统计,就变成了每次将一些边联通,然后用并查集计算减少了多少联通块。。
这样就比较容易求了。。。
 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<algorithm>
 7 #include<string>
 8 #include<map>
 9 #include<queue>
10 #include<vector>
11 #include<set>
12 #define inf 1000000000
13 #define maxn 400000+5
14 #define maxm 400000+5
15 #define eps 1e-10
16 #define ll long long
17 #define for0(i,n) for(int i=0;i<=(n);i++)
18 #define for1(i,n) for(int i=1;i<=(n);i++)
19 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
20 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
21 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
22 using namespace std;
23 int fa[maxn],head[maxn],tot,a[maxn],t[maxn],ans[maxn],top;
24 struct edge{
25     int go,next;
26 }e[maxm];
27 void insert(int u,int v){
28     e[++tot]=(edge){v,head[u]};head[u]=tot;
29 }
30 int getfa(int x){
31     if(fa[x]==x)return x;
32     else return fa[x]=getfa(fa[x]);
33 }
34 int read(){
35     int x=0,f=1;char ch=getchar();
36     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
37     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
38     return x*f;
39 }
40 int main(){
41     //freopen("input.txt","r",stdin);
42     //freopen("output.txt","w",stdout);
43     int n=read(),m=read();
44     for1(i,n)fa[i]=i;
45     for1(i,m){
46         int u=read(),v=read();
47         insert(++u,++v);
48         insert(v,u);
49     }
50     int k=read();
51     for1(i,k){a[i]=read(),a[i]++;t[a[i]]=1;}
52     int now=n-k;
53     for1(i,n)
54         if(!t[i])
55             for4(j,i)
56                 if(!t[y]){
57                     int fax=getfa(i),fay=getfa(y);
58                     if(fax!=fay){
59                         fa[fay]=fax;
60                         now--;
61                     }
62                 }
63     ans[++top]=now;
64     for3(i,k,1){
65         t[a[i]]=0;
66         ++now;
67         for4(j,a[i])
68             if(!t[y]){
69                 int fax=getfa(a[i]),fay=getfa(y);
70                 if(fax!=fay){
71                     fa[fay]=fax;
72                     now--;
73                 }
74             }
75         ans[++top]=now;
76     }
77     while(top)printf("%d\n",ans[top--]);
78     return 0;
79 }
View Code

 

posted @ 2016-05-16 15:25  HTWX  阅读(117)  评论(0编辑  收藏  举报