【Week4】岛屿 | |
|
问题描述
湖面上有 n 座岛屿,从1~n 编号。现在要湖上建桥使得岛屿连接起来。桥双向通行。
输入格式
输入第一行有两个整数 n,m。
接下来是 m 行,按照时间顺序每行是一次询问。
每行第一个整数q 代表询问的内容:
如果q=1,则接下来是两个岛屿编号a,b(a≠b);
如果q=2,则接下来是一个岛屿编号c。
输出格式
对于每个询问,按次序各输出一行作为回答:
q=1 时:如果a,b 相互可达,则输出Yes;如果a,b 相互不可达,则输出No,并在a,b之间建一座桥。
q=2 时:输出一个整数x,表示由c 出发可以到达的岛屿有x 个(不包括c 自身)。
样例输入
5 9
1 2 3
1 3 2
2 1
2 2
1 4 5
1 2 4
1 2 5
2 4
2 5
样例输出
No
Yes
0
1
No
No
Yes
3
3
提示
对于 100%的数据,2≤n≤10,000, 1≤m≤30,000。
这就是赤裸裸的并查集
并查集函数:
int find(int x){
if(father[x]!=x){
father[x]=find(father[x]);
}
return father[x];
}
全部代码·:
#include<iostream>
using namespace std;
int father[20010];
int find(int x){
if(father[x]!=x){
father[x]=find(father[x]);
}
return father[x];
}
int main(){
int n,m;
cin>>n>>m;
int a,b,q;
for(int i=1;i<=n;i++){
father[i]=i;
}
for(int i=0;i<m;i++){
int ret=0;
scanf("%d",&q);
if(q==1){
scanf("%d%d",&a,&b);
if(find(a)==find(b)){
printf("Yes\n");
}else{
printf("No\n");
int h=find(a),k=find(b);
father[h]=k;
}
}else{
scanf("%d",&a);
for(int i=1;i<=n;i++){
if(i!=a&&find(a)==find(i)){
ret++;
}
}
printf("%d\n",ret);
}
}
}