星球大战starwar

HYSBZ - 1015

 

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

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
 
第一次做这种题真的很难想,主要是不敢下手,在网上找了好多解析都是一言概之。还是觉得不要怕错,要自己按自己的思路写一下,发现其实还蛮简单的。
但感觉自己写的耗时有点多......
 #include<cstdio>
#include<cstring>
#include<iostream>
#include<cstring>
#include<vector>
#include<stack>
#include<algorithm>
using namespace std;
#define N 400002
#define T(){printf("^^^ ");}
int bc[N], waitdel[N], vis[N], ans[N];;
vector<int>gra[N];
int find(int son)
{
int fa = son;
while(fa != bc[fa])
{
fa = bc[fa];
}
//
int temp = son,k;
while(fa != bc[temp])
{
k = bc[temp];
bc[temp] = fa;
temp = k;
}
return fa;
} int main()
{
int n,m,k,x,y;
cin>>n>>m;
for(int i=; i<m; i++)
{
scanf("%d%d",&x,&y);
gra[x].push_back(y);
gra[y].push_back(x);
}
scanf("%d",&k);
memset(vis,,sizeof(vis));
for(int i=; i<k; i++)
{
scanf("%d",&waitdel[i]);
vis[waitdel[i]] = ;
}
for(int i=; i<n; i++) bc[i] = i;
int tot = n - k;
for(int i=; i<n; i++)
{
if(!vis[i])
{
for(int j=; j<gra[i].size(); j++)
{
if(!vis[gra[i][j]])
{
int x = find(i);
int y = find(gra[i][j]);
if(x != y)
{
tot --;
bc[y] = x;
}
}
}
}
}
int top = ;
for(int i=k-; i>=; i--)
{
int k = waitdel[i];
ans[top ++] = tot;
tot ++;
for(int j=; j<gra[k].size(); j++)
{
if(!vis[gra[k][j]])
{
int x = find(k);
int y = find(gra[k][j]);
if(x != y)
{
tot --;
bc[y] = x;
}
}
vis[k] = ;
}
}
ans[top++] = tot;
for(int i=top-; i>=; i--) printf("%d\n",ans[i]);
}

逆向并查集 HYSBZ1015星球大战starwar的更多相关文章

  1. 【并查集】星球大战starwar

    BZOJ1015: [JSOI2008]星球大战starwar Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 6407  Solved: 2973[Su ...

  2. ZOJ 3261 Connections in Galaxy War(逆向并查集)

    参考链接: http://www.cppblog.com/yuan1028/archive/2011/02/13/139990.html http://blog.csdn.net/roney_win/ ...

  3. HDU - 4496 City 逆向并查集

    思路:逆向并查集,逆向加入每一条边即可.在获取联通块数量的时候,直接判断新加入的边是否合并了两个集合,如果合并了说明联通块会减少一个,否则不变. AC代码 #include <cstdio> ...

  4. zoj 3261 逆向并查集+离线处理

    题意:给出一些点,每个点有权值,然后有一些边,相连.无向的.然后有一些操作 链接:点我 query a.表示从a出发的能到达的所有点权值最大的点的编号(相同取编号最小,而且权值要比自己大) desto ...

  5. HDU_4496_逆向并查集

    http://acm.hdu.edu.cn/showproblem.php?pid=4496 逆向并查集,先读取,然后从后向前join每次保存答案即可. #include<iostream> ...

  6. BZOJ 1016 星球大战starwar(逆向-并查集)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1015 题意:给出一个图.每次删掉一个点,求删掉之后连通块个数. 思路:正着做不好做,我们 ...

  7. 逆向并查集 hrbust 1913

    #include<iostream> //由于拆除并查集的方法太难或者没有#include<cstdio> //可以先将所有没有拆的桥连接 再逆向操作 断开变成连接 反向输出# ...

  8. ZOJ - 3261 逆向并查集

    思路:很巧妙的解法.如果按照常规一边读入,一边合并并查集,删边实在没办法做. 首先读入所有的操作,把所有不会被删除的边加入并查集,然后从最后一个操作开始逆向操作,当遇到删边操作,就直接把这条边加入并查 ...

  9. Connections in Galaxy War (逆向并查集)题解

    Connections in Galaxy War In order to strengthen the defense ability, many stars in galaxy allied to ...

随机推荐

  1. CRM系统(第一部分)

      阅读目录 1.需求分析 2.数据库表设计 3.起步 4.录入数据 5.知识点 1.需求分析 CRM客户关系管理软件---> 学员管理 用户:企业内部用户 用户量: 业务场景: 2.数据库表设 ...

  2. JEECG SSO kisso

    kisso: java 基于 Cookie 的 SSO 中间件 kisso https://gitee.com/baomidou/kisso kisso首页.文档和下载 - 基于 Cookie 的 S ...

  3. nodejs配置nginx 以后链接mongodb数据库

    服务器 :windows server2008 R2 反向代理 :nginx 1.15.1 for window 64位 数据库:mongodb 4 64位 使用框架express 首先下载nodej ...

  4. 区块链教程(二):比特币、区块链、以太坊、Hyperledger的关系

    不知道大家喜不喜欢音乐! 朋克音乐:诞生于七十年代中期,一种源于六十年代车库摇滚和前朋克摇滚的简单摇滚乐.它由一个简单悦耳的主旋律和三个和弦组成,经过演变,朋克已经逐渐脱离摇滚,成为一种独立的音乐,朋 ...

  5. Linux 查找文件命令 find whereis locate

    Linux 有三个查找文件的命令:find, whereis, locate 其中find 不常用,whereis与locate经常使用,因为find命令速度较慢,因为whereis与locate是利 ...

  6. [转帖]Linux命令中特殊符号

    Linux命令中特殊符号 转自:http://blog.chinaunix.net/uid-16946891-id-5088144.html   在shell中常用的特殊符号罗列如下:# ; ;; . ...

  7. [转帖]How To Be Successful

    How To Be Successful http://blog.samaltman.com/how-to-be-successful 总结一下文章的重点: 1. Compound yourself2 ...

  8. java学习之—使用栈实现字符串数字四则运算

    /** * 使用栈存储后缀表达式 * Create by Administrator * 2018/6/13 0013 * 下午 2:25 **/ public class StackX { priv ...

  9. echo "" > 和 echo "" >> 的区别

    在写shell脚本中,如果判断一个文件已经存在,但希望重写这个文件,一般用如下方式 echo "" > file.txt 这个表示清空文件的内容,如果使用 echo “” & ...

  10. NFS配置与搭建

    参考: Linux下NFS服务器的搭建与配置 https://www.cnblogs.com/liuyisai/p/5992511.html http://blog.51cto.com/hongten ...