洛谷P1197 星球大战
来源:互联网 发布:linux执行命令的过程 编辑:程序博客网 时间:2024/05/16 16:57
解题思路:
由判断联通问题想到并查集维护,但是如果每次询问都删去点跑dfs的话,显然是超时的。于是想到反着做,将删点问题转化为连边。
首先先处理出全部询问的星球被毁的联通块数,然后倒着加入询问,将与询问点联通的点遍历,记录联通块数。
输出技巧,因为是倒着处理的,可以将结果压入栈中。用栈储存结果。
详见代码
#include<iostream>#include<cstdio>#include<cstring>#include<stack>using namespace std;const int maxn=400005;int r1,r2,head[maxn],s,n,m,x,y,f[maxn],des[maxn],v[maxn],cnt,k;stack<int >ans;struct node{ int from,to;}list[maxn*2];void add(int x,int y){ list[++s].from=head[x]; list[s].to=y; head[x]=s;}int find(int x){ return f[x]==x?x:f[x]=find(f[x]);}void check(int x){ for (int i=head[x];i;i=list[i].from) { int u=list[i].to; if (v[u]) continue; r1=find(x);r2=find(u); if (r1!=r2){ cnt--;//合并一次 联通块少1 f[r1]=r2; } } if (v[x]) cnt++,v[x]=0;//如果当前点已经走过了,说明删多了,}int main(){ cin>>n>>m; for (int i=1;i<=m;i++) { scanf("%d%d",&x,&y); add(x+1,y+1);add(y+1,x+1); } for (int i=1;i<=n;i++) f[i]=i; cin>>k; for (int i=1;i<=k;i++){ scanf("%d",&x);x++; des[i]=x; v[x]=1; } cnt=n-k;//类似于并查集的初始化,每个点独立成块 for (int i=1;i<=n;i++) if (!v[i]) check(i); ans.push(cnt); for (int i=k;i>=1;i--){ check(des[i]);ans.push(cnt); } while(!ans.empty()){ cout<<ans.top()<<endl; ans.pop(); } return 0;}
阅读全文
0 0
- 洛谷 P1197 [JSOI2008]星球大战
- 洛谷 P1197 [JSOI2008]星球大战
- 洛谷 P1197 [JSOI2008] 星球大战
- 洛谷 P1197 [JSOI2008]星球大战
- [JSOI2008]星球大战 洛谷P1197
- 洛谷P1197 星球大战
- 洛谷 P1197 [JSOI2008]星球大战
- [洛谷P1197]星球大战
- 洛谷P1197 [JSOI2008]星球大战
- 洛谷P1197 [JSOI2008]星球大战
- P1197 [JSOI2008]星球大战
- [P1197][JSOI2008]星球大战
- P1197 [JSOI2008]星球大战
- 洛谷P1197 [JSOI2008]星球大战(并查集)
- 洛谷 p1197 [JSOI2008]星球大战(并查集)
- 【洛谷P1197】[JSOI2008]星球大战 反向并查集+统计连通块
- luogu P1197 [JSOI2008]星球大战 并查集 逆向思维 邻接表
- 洛谷1197 [JSOI2008]星球大战
- JSP学习笔记2
- python中的range与list函数
- effect java 学习摘要(4)
- elasticsearch的2.x 和5.x的不同之处之query
- Excel在统计分析中的应用—第四章—数据库统计函数与数据透视表-Part2-(数据库统计函数)
- 洛谷P1197 星球大战
- 用树莓派改装电风扇及实现Android遥控
- linux 内存管理概述
- 【谨记】PCB画板子的正确步骤(说多了,都是泪啊!)
- leetcode[Max Consecutive Ones]//待整理多种解法
- LeetCode 258. Add Digits
- Caffe2 入门教程
- 重载和重写的区别
- Java 基本数据类型与其包装数据类型以及字符串(String)之间的转换问题