标签:
时间限制:1000MS
内存限制:131072KB
在弹幕战完美结束之后,有趣张立马回到了房地产的大业中~因为他曾经和华莱士谈笑风生过,所以他毫不费力地弄到了一片群岛。
可是这片群岛上的一个个岛屿是孤立的。为了能在岛屿间快速地通行,并且方便泡到各个岛屿上的妹纸,有趣张决定在岛屿之间修建大桥(虽然有时候桥的面积比岛还大但是有趣张肯定不稀罕这点钱对吧)。有时候他会把2个岛屿之间连接起来(连接起来的意思就是说这两个岛屿可以通过这座桥直接互相到达)有时候为了更好地规划他需要知道岛屿之间是否是连通的,也就是说能不能从一个岛屿通过走某些桥到达另一个岛屿。所以他就把调查岛屿是否连通的任务交给了你。
输入第一行是两个整数N,M(1 <= N,M <= 200000),N表示有多少个岛屿,M表示他做了多少事.接 下来的M行中,每行包含三个整数T,A,B,如果T=1,那么表示他把标号为A和B的岛屿用桥梁连接起来.如果T=2,那么他表示想知道,标号为A和B的岛屿是否是连通的.
输出包括若干行.输入文件每出现一个T=2的操作,输入一行.如果A和B是连通的,那么输出Yes,否则输出No.(注意大小写)
4 5 2 1 3 1 1 3 2 1 3 1 3 4 2 1 4
No Yes Yes
对于20%的数据,保证有n,m<=100;
对于30%的数据,保证有n,m<=1000;
对于全部的数据,保证有n,m<=200000。
【题解】 基本的并查集,但是要路径压缩,没有路径压缩会T三个点,所以,路径压缩还是很重要滴。
因为懒就没去写按秩优化了……
1 #include<bits/stdc++.h> 2 using namespace std; 3 int pre[200001]; 4 int findset(int x) { 5 int r,i,j; 6 r=i=x; 7 while(r!=pre[r]) r=pre[r]; 8 while(i!=r) { 9 j=pre[i]; 10 pre[i]=r; 11 i=j; 12 } 13 return r; 14 } 15 void join(int a,int b) { 16 int a1=findset(a),b1=findset(b); 17 if(a1!=b1) pre[a1]=b1; 18 } 19 int main() { 20 int n,m; 21 scanf("%d%d",&n,&m); 22 for (int i=1;i<=n;++i) pre[i]=i; 23 while(m--) { 24 int t,a,b; 25 scanf("%d%d%d",&t,&a,&b); 26 if (t==2) { 27 int x=findset(a),y=findset(b); 28 if(x==y) printf("Yes\n"); 29 else printf("No\n"); 30 } 31 if (t==1) join(a,b); 32 } 33 return 0; 34 }
标签:
原文地址:http://www.cnblogs.com/TonyNeal/p/fzyzoj1859.html