【模板】並查集(洛谷P3367)
阿新 • • 發佈:2018-11-06
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; }