洛谷P1197 [JSOI2008]星球大战(并查集)
2018-03-23 20:41
267 查看
[JSOI2008]星球大战
题目描述很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系。某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球。这些星球通过特殊的以太隧道互相直接或间接地连接。
但好景不长,很快帝国又重新造出了他的超级武器。凭借这超级武器的力量,帝国开始有计划地摧毁反抗军占领的星球。由于星球的不断被摧毁,两个星球之间的通讯通道也开始不可靠起来。现在,反抗军首领交给你一个任务:给出原来两个星球之间的以太隧道连通情况以及帝国打击的星球顺序,以尽量快的速度求出每一次打击之后反抗军占据的星球的连通块的个数。(如果两个星球可以通过现存的以太通道直接或间接地连通,则这两个星球在同一个连通块中)。
输入输出格式
输入格式:
输入文件第一行包含两个整数,N (1 <= N <= 2M) 和M (1 <= M <= 200,000),分别表示星球的数目和以太隧道的数目。星球用0~N-1的整数编号。
接下来的M行,每行包括两个整数X, Y,其中(0<=X<>Y
#include <cstdio> #define N 700000 using namespace std; struct arr { int to,nxt; }a ; int f ,ls ,b ,l,n,m,k; bool fl ,vis ; int ans ; int find(int x) { if (f[x]==x) return x; return f[x]=find(f[x]); } void add(int x,int y) { a[++l].to=y; a[l].nxt=ls[x]; ls[x]=l; } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); x++;y++; add(x,y); add(y,x); } for (int i=1;i<=n;i++) f[i]=i; scanf("%d",&k); for (int i=1;i<=k;i++) { scanf("%d",&b[i]); b[i]++; fl[b[i]]=true; } int p=n-k; for (int i=1;i<=n;i++) if (!fl[i]) { for (int j=ls[i];j;j=a[j].nxt) if (!fl[a[j].to]) { int u=find(i); int v=find(a[j].to); if (u!=v) { f[v]=u; p--; } } } ans[k]=p; for (int i=k;i>0;i--) { fl[b[i]]=false; p++; for (int j=ls[b[i]];j;j=a[j].nxt) if (!fl[a[j].to]) { int u=find(b[i]); int v=find(a[j].to); if (u!=v) { f[v]=u; p--; } } ans[i-1]=p; } for (int i=0;i<=k;i++) printf("%d\n",ans[i]); }
相关文章推荐
- 并查集-洛谷P1197 [JSOI2008]星球大战
- 【洛谷P1197】[JSOI2008]星球大战 反向并查集+统计连通块
- 并查集【洛谷P1197】 [JSOI2008]星球大战
- 洛谷P1197 [JSOI2008]星球大战(并查集)
- 洛谷 p1197 [JSOI2008]星球大战(并查集)
- 洛谷 P1197 [JSOI2008]星球大战
- 洛谷 P1197 [JSOI2008]星球大战
- 洛谷 P1197 [JSOI2008]星球大战
- 洛谷 P1197 [JSOI2008]星球大战
- 洛谷 P1197 [JSOI2008]星球大战
- 洛谷Oj-P1197 [JSOI2008]星球大战-并查集
- 洛谷P1197 [JSOI2008]星球大战
- P1197 [JSOI2008]星球大战(并查集判断连通块+正难则反)
- 洛谷 P1197 [JSOI2008] 星球大战
- 洛谷P1197 [JSOI2008]星球大战
- 洛谷 P1197 [JSOI2008]星球大战
- 洛谷 1197 [JSOI2008]星球大战 并查集
- 洛谷P1197 [JSOI2008]星球大战
- 并查集【p1197】[JSOI2008]星球大战
- 洛谷 P1197 [JSOI2008]星球大战