P1714【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。
问题分析:
问题1:查询a,b两个元素是否位于同一个集合,若不是,将两个集合合并。
问题2:询问元素c所在集合的元素的个数。
合并时 集合个数相加
code:
// #include<bits/stdc++.h> using namespace std; #define maxnn 30100 int f[maxnn],cnt[maxnn]; int q; int n,m; int gf(int v) { return f[v]==v? v: f[v]=gf(f[v]); } void merge(int x,int y) { int fx=gf(x); int fy=gf(y); if(fx!=fy) { f[fx]=fy; cnt[fy]+=cnt[fx]; } } int main() { cin>>n>>m; int x,y; for(int i=1;i<=n;i++) f[i]=i,cnt[i]=1; for(int i=1;i<=m;i++) { cin>>q; if(q==1) { cin>>x>>y; if(gf(x)==gf(y)) cout<<"Yes"<<endl; else cout<<"No"<<endl; if(!(gf(x)==gf(y))) merge(x,y); } else { cin>>x; cout<<cnt[gf(x)]-1<<endl; } } }