NOJ[1508] 火烧赤壁2
来源:互联网 发布:java并发实战 编辑:程序博客网 时间:2024/04/20 09:39
- 时间限制: 1000 ms 内存限制: 65535 K
- 问题描述
- 上次出了一道火烧赤壁的题目给当时的新生,也就是你们的上一届学长们做,那么这次,我又想到了另一个想法。
上次的火烧赤壁的题号为1274
这次稍微难一点,我们来个火烧赤壁2吧。
Hungar个人很喜欢曹操这个人,所以这次有机会穿越到三国时代,他想帮助曹操打赢赤壁之战。
但是他去晚了,当他穿越到那的时候发现大火已经在蔓延了,所以他能做的就是马上告诉曹操把已经着火的船的锁链(船与船相连都是靠锁链达到的)给破坏掉使火不会蔓延到附近的船只。
现在告诉你曹操一共有N艘船,M条铁链,船只编号从0开始到n-1。
然后再告诉你依次着火的船只编号,问舍弃那艘船以后,剩下的船只能形成几个连通块(只要是被铁链连在一起的全部船只,就算一共连通块)。
船与船之间可能存在多条锁链。 - 输入
- 输入包括第一行两个整数,N(1 <= N <= 2M)和M(1 <= M <= 200,000)。
接下来M行,每行包括两个整数x和y(x != y),分别表示编号为x和y的船只被一根锁链连起来。
再接下来一个正整数T表示着火船只的数量。
接下来T行,每行包含一个整数z表示被烧船只的编号,编号不会出现一样的,也就是说已经被烧的船只不会再去烧它。 - 输出
- 输出z+1个数,第一行为着火前这些船的连通块数,后z行表示每次依次烧掉一只船后,剩下的连通块数。
- 样例输入
8 130 11 66 55 00 61 22 33 44 57 17 27 63 6516357
- 样例输出
111233
- 提示
并查集
- 来源
Hungar
用最朴素的做法,我们要建很多次图,时间上不允许,所以得想点什么优化,本弱刚看到也没什么头绪,后来听说要把操作保留,然后逆序操作,瞬间就折服了
我们先构建一张图,其中不包括烧掉的点和边,那么这就是最后的情况了,之后我们每次都添加被烧的那个点和附属的边。原来是去点,现在相当于从最后加点。
#include<stdio.h>#include<string.h>const int maxn=400010;int father[maxn];bool flag[maxn];int turn[maxn];int ans2[maxn]; struct node{int to;int next;}edge[maxn];int head[maxn];int tot,ans;void addedge(int from,int to){edge[tot].to=to;edge[tot].next=head[from];head[from]=tot++;}int find(int x){if(father[x]==-1) return x; return father[x]=find(father[x]);}void Union(int x,int y){int a=find(x);int b=find(y);if(a!=b){father[a]=b;ans--;}}int main(){int n,m;while(~scanf("%d%d",&n,&m)){memset(flag,0,sizeof(flag));memset(head,-1,sizeof(head));memset(father,-1,sizeof(father));tot=0;int x,y;for(int i=0;i<m;i++){scanf("%d%d",&x,&y);addedge(x,y);addedge(y,x);} int t; scanf("%d\n",&t); ans=n-t; for(int i=0;i<t;i++) { scanf("%d",&turn[i]); flag[turn[i]]=1; } for(int i=0;i<n;i++) { if(flag[i]) continue; for(int j=head[i];j!=-1;j=edge[j].next) if(!flag[edge[j].to]) Union(i,edge[j].to); //最后的情况时2个点都没被烧掉的才可以并 } ans2[t]=ans; for(int i=t-1;i>=0;i--) {flag[turn[i]]=0;ans++; for(int j=head[turn[i]];j!=-1;j=edge[j].next) { if(!flag[edge[j].to]) Union(turn[i],edge[j].to); } ans2[i]=ans; } for(int i=0;i<=t;i++) printf("%d\n",ans2[i]);}return 0;}
0 0
- NOJ[1508] 火烧赤壁2
- NOJ——1508火烧赤壁2(并查集+启发式合并+逆序加边)
- nbut 1058 火烧赤壁 2
- NBUT 1508 火烧赤壁2【离线+逆序并查集】
- 火烧赤壁的故事
- 火烧赤壁 洛谷 vijos
- 洛谷p1496火烧赤壁
- 2774 火烧赤壁(排序贪心)
- 1165 火烧赤壁 vijosoj (数组模拟)
- vijos 1165_火烧赤壁_离散
- vijos p1103校门外的树 和 P1165火烧赤壁
- (NOIP2015)复赛模拟试题 vijos1165 火烧赤壁
- 赤壁
- 火烧赤壁(vijos某次模拟赛题目noip2004校门口外的树加强版)略高于noip普及组难度
- Noj
- 赤壁续集日本票房惊爆2亿
- 前导赤壁分析(2)——调色板资源文件
- 赤壁风云
- 【leetcode】Simplify Path
- opencv分水岭算法对图像进行分割
- 基于AVR128的简单Modbus协议实现
- Java常用监听器
- 查看 Oracle11g 的字符集
- NOJ[1508] 火烧赤壁2
- 【NOIP模拟】20140814 题解 & 总结
- Sizeof与Strlen的区别与联系
- 信号量,PV操作
- 初始R 语言
- linux netstart命令
- Java虚拟机的JVM垃圾回收机制
- 设计模式之观察者模式
- [JavaScript]-----函数