1. 程式人生 > >【模板】並查集(洛谷P3367)

【模板】並查集(洛谷P3367)

Description

  如題,現在有一個並查集,你需要完成合並和查詢操作。

Input

  第一行包含兩個整數\(N\)\(M\),表示共有\(N\)個元素和\(M\)個操作。
  接下來M行,每行包含三個整數\(opt\)\(a\)\(b\)
  當\(opt=1\)時,將\(a\)\(b\)所在的集合合併
  當\(opt=2\)時,輸出\(a\)\(b\)是否在同一集合內,是的話輸出\(Y\);否則話輸出\(N\)

Output

  如上,對於每一個opt=2的操作,都有一行輸出,每行包含一個大寫字母,為Y或者N

Solution

路徑壓縮

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m,f[10010],opt,x,y;
inline int read()
{
    int ans=0;
    char ch=getchar();
    while (ch<'0' || ch>'9') ch=getchar();
    while (ch>='0' && ch<='9')
    {
        ans=ans*10+ch-'0';
        ch=getchar();
    }
    return ans;
}
int find(int x)
{
    if (f[x]==x) return x;
    return f[x]=find(f[x]);
}
int main()
{
    n=read(),m=read();
    for (int i=1;i<=n;i++) f[i]=i;
    while (m--)
    {
        opt=read(),x=read(),y=read();
        if (opt==1)
        {
            int fx=find(x),fy=find(y);
            if (fx!=fy) f[fx]=fy;
        }
        else
        {
            int fx=find(x),fy=find(y);
            if (fx!=fy) printf("N\n"); else printf("Y\n");
        }
    }
    return 0;
}

按秩合併

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m,f[100010],dep[100010],opt,x,y;
inline int read()
{
    int ans=0;
    char ch=getchar();
    while (ch<'0' || ch>'9') ch=getchar();
    while (ch>='0' && ch<='9')
    {
        ans=ans*10+ch-'0';
        ch=getchar();
    }
    return ans;
}
int find(int x)
{
    if (f[x]==x) return x;
    return find(f[x]);
}
int main()
{
    n=read(),m=read();
    for (int i=1;i<=n;i++) f[i]=i,dep[i]=0;
    while (m--)
    {
        opt=read(),x=read(),y=read();
        if (opt==1)
        {
            int fx=find(x),fy=find(y);
            if (fx==fy) continue;
            if (dep[fx]<dep[fy]) f[fx]=fy;
            else if (dep[fx]>dep[fy]) f[fy]=fx;
            else
            {
                f[fx]=fy;
                dep[fy]++;
            }
        }
        else
        {
            int fx=find(x),fy=find(y);
            if (fx!=fy) printf("N\n"); else printf("Y\n");
        }
    }
    return 0;
}