JSOI2008 星球大战 [并查集]
题目描述
很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系。
某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球。这些星球通过特殊的以太隧道互相直接或间接地连接。
但好景不长,很快帝国又重新造出了他的超级武器。凭借这超级武器的力量,帝国开始有计划地摧毁反抗军占领的星球。由于星球的不断被摧毁,两个星球之间的通讯通道也开始不可靠起来。
现在,反抗军首领交给你一个任务:给出原来两个星球之间的以太隧道连通情况以及帝国打击的星球顺序,以尽量快的速度求出每一次打击之后反抗军占据的星球的连通快的个数。(如果两个星球可以通过现存的以太通道直接或间接地连通,则这两个星球在同一个连通块中)。
输入输出格式
输入格式:
输入文件第一行包含两个整数, NN ( 1 < = N < = 2M ) 和 MM ( 1 < = M < = 200,000 ),分别表示星球的数目和以太隧道的数目。星球用 0 ~ N-1 的整数编号。
接下来的 M 行,每行包括两个整数 X , Y ,其中( 0 < = X <> Y 表示星球 xx 和星球 yy 之间有 “以太” 隧道,可以直接通讯。
接下来的一行为一个整数 k ,表示将遭受攻击的星球的数目。
接下来的 k 行,每行有一个整数,按照顺序列出了帝国军的攻击目标。这 k 个数互不相同,且都在 0 到 n-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
说明
[JSOI2008]
题解
也是一道用并查集的题目
看到题目描述中每次都会攻击一个点,这个点及与其相连的边都会消失,但是并查集并不支持删除操作,怎么办呢?
我们可以倒序处理,首先把所有被攻击的点打上标记,然后把所有点都扫一遍,把没有标记的点建图,当然这个图不一定连通,也就是说可能剩下的点组成的集合不只一个连通块,而这个连通快的数量就是k次攻击后连通块的数量,把它保存下来,再倒着处理,也就是for(i=k~1)把第i次删除的点加上再建图,再统计连通块的数量,这就是第i-1攻击后的答案,特别地当i=1时,ans[i-1]保存的就是最开始没有受到攻击时连通块的数量
#include<bits/stdc++.h>
#define in(i) (i=read())
using namespace std;
int read()
{
    int ans=0,f=1;
    char i=getchar();
    while(i<'0' || i>'9'){
        if(i=='-') f=-1;
        i=getchar();
    }
    while(i>='0' && i<='9'){
        ans=(ans<<1)+(ans<<3)+i-'0';
        i=getchar();
    }
    return ans*f;
}
int n,m,k;
int len;
int fa[400010];
struct edgec {
    int from,to,next;
}e[4000010];
int head[400010];
int vis[400010],ans[400010],h[400010];
void add(int a,int b) {
    e[++len].to=b;
    e[len].from=a;
    e[len].next=head[a];
    head[a]=len;
}
int find(int x) {
    if(fa[x]!=x)	fa[x]=find(fa[x]);
    return fa[x];
}
int main()
{
    in(n);in(m);
    for(int i=0;i<n;i++ )	fa[i]=i;
    for(int i=1;i<=m;i++) {
        int a,b;
        in(a);in(b);
        add(a,b);
        add(b,a);
    }
    in(k);
    for(int i=1;i<=k;i++) {
        int x;in(x);
        vis[x]=1;
        h[i]=x;
    }
    int tot=n-k;
    for(int i=1;i<=2*m;i++) {
        int x=e[i].from,y=e[i].to;
        if(!vis[x] && !vis[y]) {
            int fx=find(x),fy=find(y);
            if(fx!=fy){
                tot--;
                fa[fx]=fy;
            }
        }
    }
    ans[k+1]=tot;
    for(int t=k;t>=1;t--) {
        int u=h[t];
        vis[u]=0;
        tot++;
        for(int i=head[u];i;i=e[i].next) {
            int to=e[i].to;
            int x=find(u),y=find(to);
            if(!vis[to] && x!=y) {
                tot--;
                fa[x]=y;
            }
        }
        ans[t]=tot;
    }
    for(int i=1;i<=k+1;i++) {
        cout<<ans[i]<<endl;
    }
    return 0;
}
												
											JSOI2008 星球大战 [并查集]的更多相关文章
- 洛谷P1197 [JSOI2008] 星球大战 [并查集]
		
题目传送门 星球大战 题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系. 某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这 ...
 - P1197 [JSOI2008]星球大战[并查集+图论]
		
题目来源:洛谷 题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治着整个星系. 某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球 ...
 - P1197 [JSOI2008]星球大战  并查集 反向
		
题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治着整个星系. 某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过特殊的以太隧 ...
 - [bzoj1015][JSOI2008]星球大战——并查集+离线处理
		
题解 给定一张图,支持删点和询问连通块个数 按操作顺序处理的话要在删除点的同时维护图的形态(即图具体的连边情况),这是几乎不可做的 我们发现,这道题可以先读入操作,把没删的点的边先连上,然后再倒序处理 ...
 - 洛谷 P1197 [JSOI2008]星球大战——并查集
		
先上一波题目 https://www.luogu.org/problem/P1197 很明显删除的操作并不好处理 那么我们可以考虑把删边变成加边 只需要一波时间倒流就可以解决拉 储存删边顺序倒过来加边 ...
 - BZOJ_1015_星球大战_[JSOI2008]_(并查集)
		
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1015 n 个点,被 m 条边相连.进行k次删点操作,问第一次操作前和每次操作后的集合数(直接或 ...
 - 【BZOJ1015】【JSOI2008】星球大战 并查集
		
题目大意 给你一张\(n\)个点\(m\)条边的无向图,有\(q\)次操作,每次删掉一个点以及和这个点相邻的边,求最开始和每次删完点后的连通块个数. \(q\leq n\leq 400000,m\le ...
 - 【JSOI2008】星球大战  并查集
		
题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治着整个星系. 某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过特殊的以太隧 ...
 - BZOJ-1015  StarWar星球大战   并查集+离线处理
		
1015: [JSOI2008]星球大战starwar Time Limit: 3 Sec Memory Limit: 162 MB Submit: 4105 Solved: 1826 [Submit ...
 
随机推荐
- poj_2339
			
参考:https://blog.csdn.net/yzl_rex/article/details/7600906 https://blog.csdn.net/acm_JL/article/detail ...
 - C语言运算符优先级和结合性
			
运算符优先级和结合性 优先级 运算符 结合性 ...
 - gp更新来的太快
			
意外总是会发生 添加一个判断function的分支,过滤掉function,其实也考虑再进一步去分析它的作用,稍后再议. 更新一下 var gnp = { get: function(url) { r ...
 - c# string.format和tostring()
			
字符 说明 示例 输出 C 货币 string.Format("{0:C3}", 2) $2.000 D 十进制 string.Format("{0:D3}", ...
 - P2212 [USACO14MAR]浇地Watering the Fields
			
P2212 [USACO14MAR]浇地Watering the Fields 题目描述 Due to a lack of rain, Farmer John wants to build an ir ...
 - 剁了xp,醉了win7
			
装完win7,安装各种软件完毕,重启,然并卵. cpu,内存飙升!! svchost.exe这个进程内存发疯了一样往上飙升 从 几十兆 到占用1个多G, 纳尼, 总共物理内存才2G. ╮(╯▽╰) ...
 - luogu2387 [NOI2014]魔法森林
			
这题和水管局长很像,枚举 \(a\) 的边然后维护关于 \(b\) 的最小生成树就可以了. 1A呐>_< #include <algorithm> #include <i ...
 - LINUX系统配置相关
			
修改系统引导文件 grub.cfg的文件位置 /boot/grub/grub.cfg set default="4" 默认windows是在第四个选项 set timeout ...
 - ExtJs工具篇(2)——Aptana Studio 3 汉化
			
本身用的是中文版本的,但是输入一些中文后,竟然有乱码,所以就想把它汉化.在网上搜索了一下,把步骤记录如下: 首先到这个网站去 http://aptana.com/support 选择View Docu ...
 - 【JS笔记】闭包
			
首先看执行环境和作用域的概念.执行环境定义了变量或函数有权访问的其他数据,决定它们的行为,每个执行环境都有一个与其关联的变量对象,保存执行环境中定义的变量.当代码在一个环境中执行时,会创建变量对象的一 ...