題解之洛谷P1551——並查集的板子題(第一次發部落格如有不好請多多諒解)
阿新 • • 發佈:2019-01-23
【題目背景】
若某個家族人員過於龐大,要判斷兩個是否是親戚,確實還很不容易,現在給出某個親戚關係圖,求任意給出的兩個人是否具有親戚關係。
【題目描述】
規定:x和y是親戚,y和z是親戚,那麼x和z也是親戚。如果x,y是親戚,那麼x的親戚都是y的親戚,y的親戚也都是x的親戚。
【輸入輸出格式】
【輸入格式】第一行:三個整數n,m,p,(n<=5000,m<=5000,p<=5000),分別表示有n個人,m個親戚關係,詢問p對親戚關係。
以下m行:每行兩個數Mi,Mj,1<=Mi,Mj<=N,表示Mi和Mj具有親戚關係。
接下來p行:每行兩個數Pi,Pj,詢問Pi和Pj是否具有親戚關係。
【輸出格式】
P行,每行一個’Yes’或’No’。表示第i個詢問的答案為“具有”或“不具有”親戚關係。
【輸入輸出樣例】
【輸入樣例】
6 5 3
1 2
1 5
3 4
5 2
1 3
1 4
2 3
5 6
【輸出樣例】
Yes
Yes
No
【說明】
非常簡單的並查集入門題哦!!!
【解題思路】
看到這個題的時候想起的基本演算法有:Floyd求連通性、搜尋、並查集
再瞄一眼資料範圍,Floyd肯定是GG了,搜尋O(N^2)有點勉強的感覺,並查集加了路徑壓縮後接近線性,好了就他了
吐槽下,感覺資料範圍有點小了,1e6的資料感覺正好,甚至可以設定成1e7
廢話不多說下面沾AC程式碼:
/* copy by Apojacsleam */ #include<cstdio> #include<cctype> #define N 5001 int readin(); int n,m,p,fa[N]; int find(int x) { if(fa[x]==x) return x; return fa[x]=find(fa[x]); } int main() { n=readin();m=readin();p=readin(); for(register int i=1;i<=n;i++) fa[i]=i; int a,b; for(register int i=1;i<=m;i++) { a=readin();b=readin(); int r1=find(a),r2=find(b); if(r1!=r2) fa[r2]=r1; } for(register int i=1;i<=p;i++) { a=readin();b=readin(); int r1=find(a),r2=find(b); if(r1==r2) puts("Yes"); else puts("No"); } return 0; } int readin() { int fz=0;char ch=getchar();bool XX=true; for(;!isdigit(ch);ch=getchar()) if(ch=='-') XX=false; for(;isdigit(ch);ch=getchar()) fz=(fz<<3)+(fz<<1)+ch-48; return XX?fz:(~fz)+1; }