岛屿(并查集)

P1714【Week4】岛屿
时间限制 : 10000 MS   空间限制 : 128000 KB
问题描述

湖面上有 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;
        }
    }
    
    
    
}
刀剑映出了战士的心。而我的心,漆黑且残破
原文地址:https://www.cnblogs.com/OIEREDSION/p/11260121.html