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

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


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


题解:

  显然一看就知道是并查集,但是需要不断删除点,然而并查集并不支持删除操作。而且路径压缩过后,每个点显然只与根节点有关系而找不到子节点与其他子节点的关系了,所以只能反过来做,先求出所有星球被炸完后的连通分量,再把被炸的星球一个一个加上去,维护连通分量个数即可。

  另外最后输出答案的时候用cout就runtime error??害得我查了一小时的bug...我真他娘服了

  1. #include <iostream>
  2. #include <string.h>
  3. #include <cstdio>
  4. #include <algorithm>
  5. #include <queue>
  6. #pragma warning ( disable : 4996 )
  7.  
  8. #define sigma_size 26
  9.  
  10. using namespace std;
  11.  
  12. const int inf = 0x3f3f3f3f;
  13. const int vspot = 4e5 + ;
  14. const int espot = 2e5 + ;
  15.  
  16. struct node {
  17. int to;
  18. int next;
  19. }e[vspot];
  20.  
  21. int N, M;
  22. int cnt, linjie[vspot], pre[vspot], num;
  23. int hit[vspot]; //hit[x]表示x号星球是否毁灭
  24. int fin[vspot]; //fin记录被毁灭星球的顺序号数
  25. int ans;
  26.  
  27. int find( int x ) { return x==pre[x]?x:pre[x]=find(pre[x]); }
  28.  
  29. void add( int x, int y )
  30. {
  31. e[cnt].to = y; e[cnt].next = linjie[x]; linjie[x] = cnt++;
  32. e[cnt].to = x; e[cnt].next = linjie[y]; linjie[y] = cnt++;
  33. }
  34.  
  35. void init()
  36. {
  37. cnt = num = ;
  38. ans = N;
  39. memset( linjie, -, sizeof(linjie) );
  40. for( int i = ; i <= N; i++ )
  41. pre[i] = i;
  42. }
  43.  
  44. void read()
  45. {
  46. int x, y;
  47. for ( int i = ; i < M; i++ )
  48. {
  49. scanf( "%d %d", &x, &y );
  50. add( x, y );
  51. }
  52.  
  53. cin >> num;
  54. for ( int i = ; i <= num; i++ )
  55. {
  56. scanf("%d", &x);
  57. fin[i] = x;
  58. hit[x] = ;
  59. }
  60. }
  61.  
  62. void merge(int x)
  63. {
  64. int xr = find(x);
  65. for ( int y = linjie[x]; y+; y = e[y].next )
  66. if ( !hit[e[y].to] )
  67. {
  68. int yr = find(e[y].to);
  69. if ( yr != xr )
  70. {
  71. pre[yr] = xr;
  72. ans--;
  73. }
  74. }
  75. }
  76.  
  77. int main()
  78. {
  79. cin >> N >> M;
  80. init();
  81. read();
  82. //先 画出图
  83. for( int i = ; i < N; i++ )
  84. {
  85. if ( !hit[i] )
  86. merge(i);
  87. else
  88. ans--; //一个星球被毁灭时,它本身就不算一个连通分量
  89. }
  90. fin[num+] = ans; //最后一个星球被毁灭后剩下的连通分量个数
  91. //一个一个加点和加边
  92. for ( int i = num; i > ; i-- )
  93. {
  94. hit[fin[i]] = ;
  95. ans++; //将一个星球加回来时,相当于多了一个连通分量
  96.  
  97. merge(fin[i]);
  98. fin[i] = ans;
  99. }
  100. ////////////////用cout就会runtime error/////////////////////////
  101. for( int i = ; i <= num+; i++ )
  102. printf("%d\n",fin[i]);
  103.  
  104. return ;
  105. }

HYSBZ 1015/BZOJ1015 星球大战starwar的更多相关文章

  1. bzoj1015:1015: [JSOI2008]星球大战starwar

    应该是全部读入之后再添加边用并查集就可以了. yyl用空间换时间.u[]v[]等将边预存起来. #include<cstdio> #include<cstring> #incl ...

  2. 1015: [JSOI2008]星球大战starwar

    1015: [JSOI2008]星球大战starwar Time Limit: 3 Sec Memory Limit: 162 MB Description 很久以前,在一个遥远的星系,一个黑暗的帝国 ...

  3. [1015][JSOI2008]星球大战starwar(并查集)

    1015: [JSOI2008]星球大战starwar Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 2124  Solved: 909[Submit] ...

  4. BZOJ 1015: [JSOI2008]星球大战starwar 并查集

    1015: [JSOI2008]星球大战starwar Description 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝 ...

  5. 【BZOJ】1015: [JSOI2008]星球大战starwar

    1015: [JSOI2008]星球大战starwar 题意:一个点数为N(1<= 40w),边数为M(1<=20w)的图,总共删除k个节点,问开始以及每次删除一个节点之后图的连通块数? ...

  6. BZOJ 1015 [JSOI2008]星球大战starwar

    1015: [JSOI2008]星球大战starwar Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 3551  Solved: 1581[Submit ...

  7. 【BZOJ】1015: [JSOI2008]星球大战starwar(并查集)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1015 看了题解的囧T_T,一开始以为是求割点,但是想到割点不能统计.... 这题用并查集,思想很巧妙 ...

  8. bzoj 1015: [JSOI2008]星球大战starwar (逆向思维+并查集)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1015 思路: 题目是要我们对当前图拆掉k个点,问,每拆一个点后图中有多少个联通块,我们可以逆 ...

  9. BZOJ 1015: [JSOI2008]星球大战starwar(并查集求连通块+离线处理)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1015 题意: 思路:好题啊!!! 这道题目需要离线处理,先把所有要删的点给保存下来,然后逆序加点,这 ...

随机推荐

  1. 《初识Python之认识常量type函数》

    <初识Python之认识常量type函数> 1.2 认识常量 1.常量:我们用的就是它字面意义上的值或内容. 2.数字(Number) (1)整数表示:97. (2)浮点数表示:5.29 ...

  2. jquery 表单验证插件

    其他: <form action=""> First name: <input type="text" name="FirstNam ...

  3. pom.xml文件配置maven仓库地址

    中央仓库就是Maven的一个默认的远程仓库,Maven的安装文件中自带了中央仓库的配置($M2_HOME/lib/maven-model-builder.jar) 在很多情况下,默认的中央仓库无法满足 ...

  4. lync sdk 二次开发

    1.关于 UI Suppression Mode http://blog.thoughtstuff.co.uk/2014/08/the-6-things-you-need-to-know-about- ...

  5. [转]WPF的BitmapImage的文件无法释放及内存泄露的问题

    相信用过WPF的BitmapImage的,都在用类似这样的代码来解决文件无法删除的问题! 如果看看msdn上简单的描述,可以看到这样的说明: 如果 StreamSource 和 UriSource 均 ...

  6. Java虚拟机性能管理神器 - VisualVM(7) 排查JAVA应用程序线程泄漏【转】

    Java虚拟机性能管理神器 - VisualVM(7) 排查JAVA应用程序线程泄漏[转] 标签: javajvm线程泄漏 2015-03-11 19:47 1098人阅读 评论(0) 收藏 举报   ...

  7. 辨析JspWriter和PrintWriter

    JspWriter和PrintWriter的区别? JspWriter相当于带缓冲的PrintWriter 如何控制out缓冲? 通过设置JSP页面page指令的buffer属性, 可以调整out缓冲 ...

  8. Angular CLI ng常用指令整理

    一.组件创建 ng generate component heroes 二.运行项目 ng serve --open //--open 立即打开 三.创建指令 ng g directive my-ne ...

  9. Jenkins 简单安装使用

    一.介绍 Jenkins 是一款业界流行的开源持续集成工具,广泛用于项目开发,具有自动化构建.测试和部署等功能.由于 jenkins是基于java环境运行的,所以首先需要安装java环境 二.安装 1 ...

  10. window 批量修改或去除文件后缀名

    for /r %i in (*.!ut) do ren "%i" *. 转自:https://blog.csdn.net/zhang_ruisen/article/details/ ...