2017-07-08【NOIP提高组】模拟赛B组-连通块(connect)-题解
来源:互联网 发布:单纯和傻的区别 知乎 编辑:程序博客网 时间:2024/05/22 03:50
原题:
http://172.16.0.132/senior/#contest/show/2041/1
题目描述:
你应该知道无向图的连通块的数量,你应该知道如何求连通块的数量。当你兴奋与你的成就时,破坏王Alice拆掉了图中的边。当她发现,每删去一条边,你都会记下边的编号,同时告诉她当前连通块的个数。
然而,对边编号简直就是个悲剧,因为Alice为了刁难你,拆掉编号从l到r的边,当然你需要做的事情就是求连通块的个数。如果你答对了,Alice会把拆掉的边装好,迚行下一次破坏。如果你无法完成这个任务,Alice会彻底毁了你的图。
进行完足够多次之后,Alice觉得无聊,就玩去了,而你却需要继续做第三题。
输入:
第一行两个整数n,m,表示点数和边数。
之后m行每行两个整数x,y,表示x与y之间有无向边。(按读入顺序给边编号,编号从1开始)
一行一个整数k,表示Alice的破坏次数。
之后k行,每行两个整数l,r。
输出:
k行,每行一个整数。
样例输入:
6 5
1 2
5 4
2 3
3 1
3 6
6
1 3
2 5
1 5
5 5
2 4
3 3
样例输出:
4
5
6
3
4
2
数据范围限制:
对于30%的数据,n<=100,k<=10
对于60%的数据,k<=1000
对于100%的数据,n<=500,m<=10000,k<=20000,1<=l<=r<=m
分析:
并查集
不妨设一个F[i]数组,记录只添加前i条边时,所有节点的联通情况。
再设一个G[i]数组,记录只添加i-m条边时,所有节点的联通情况。
对于每一个询问只要把F[l-1],G[r+1]合并即可。
实现:
#include<cstdio>#include<algorithm>#include<cstring>using namespace std;int x,y,ans,k,xx,yy,n,m,i,f[10001][501],g[10001][501],mg[501],mk[501],a[10001][3];int getf(int x,int i){return f[i][x]==x?x:(f[i][x]=getf(f[i][x],i));}int getg(int x,int i){return g[i][x]==x?x:(g[i][x]=getg(g[i][x],i));}int get(int x){ return mg[x]==x?x:(mg[x]=get(mg[x]));}int main(){ freopen("connect.in","r",stdin);freopen("connect.out","w",stdout); scanf("%d%d",&n,&m); for(i=1;i<=m;i++) scanf("%d%d",&a[i][1],&a[i][2]); for(i=1;i<=n;i++) f[0][i]=i,g[m+1][i]=i; for(i=1;i<=m;i++) { memcpy(f[i],f[i-1],sizeof(f[i])); xx=getf(a[i][1],i); yy=getf(a[i][2],i); if(xx!=yy) f[i][xx]=yy; } for(i=m;i>=1;i--) { memcpy(g[i],g[i+1],sizeof(g[i])); xx=getg(a[i][1],i); yy=getg(a[i][2],i); if(xx!=yy) g[i][xx]=yy; } scanf("%d",&k); while (k--) { scanf("%d%d",&x,&y); if(x>y) swap(x,y); ans=0; memcpy(mg,f[x-1],sizeof(mg)); for(i=1;i<=n;i++) { xx=get(mg[i]); yy=get(g[y+1][i]); if(xx!=yy) mg[xx]=yy; } for(i=1;i<=n;i++) { xx=get(mg[i]); if(mk[xx]!=k) mk[xx]=k,ans++; } printf("%d\n",ans); }}
阅读全文
0 0
- 2017-07-08【NOIP提高组】模拟赛B组-连通块(connect)-题解
- 2017-07-08【NOIP提高组】模拟赛B组-山峰(summits)-题解
- 2017.10.07【NOIP提高组】模拟赛B组 偷懒的西西 题解
- 2017.10.07【NOIP提高组】模拟赛B组 瑰丽华尔兹 题解
- 2017.10.07【NOIP提高组】模拟赛B组 Heatwave 题解
- 2016.10.07【初中部 NOIP提高组 】模拟赛C题解
- 计蒜客 2017 NOIP 提高组模拟赛(一)题解
- 2017.1.15【初中部 NOIP提高组】模拟赛B组 寻找羔羊(agnus) 题解
- 2017.1.15【初中部 NOIP提高组】模拟赛B组 重复字符串(powerstr) 题解
- 2017.1.15【初中部 NOIP提高组】模拟赛B组 七天使的通讯(angelus) 题解
- 2017.10.06【NOIP提高组】模拟赛B组 整除 题解
- 2017.10.06【NOIP提高组】模拟赛B组 新壳栈 题解
- 2017.10.06【NOIP提高组】模拟赛B组 青蛙 题解
- 2017.07.07【NOIP提高组】模拟赛B组
- 2017.07.07【NOIP提高组】模拟赛B组小结
- 2017.08.07【NOIP提高组】模拟赛B组
- 2017.07.08【NOIP提高组】模拟赛B组
- 2017.07.08【NOIP提高组】模拟赛B组小结
- 2017-07-08【NOIP-普及组】模拟赛C组-count-题解
- jzoj. 3519. 【NOIP2013模拟11.6A组】灵能矩阵(pylon)
- 2017-07-08【NOIP-普及组】模拟赛C组-sort-题解
- TCP的三次握手和四次挥手详解
- 2017-07-08【NOIP-普及组】模拟赛C组-sum-题解
- 2017-07-08【NOIP提高组】模拟赛B组-连通块(connect)-题解
- ToBase64String方法
- 理解Linux系统负荷
- 2017-07-08【NOIP提高组】模拟赛B组-山峰(summits)-题解
- suse系统解决ssh登录慢的办法
- Win7风格的MFC
- 算法系列——Reverse Linked List
- WooCommerce——修改“Related Products“文字
- 解读Secondary NameNode的功能