1. 程式人生 > 資訊 >贈氣泡酒 4 瓶,江小白果立方果酒 168ml*2 瓶 24.8 元

贈氣泡酒 4 瓶,江小白果立方果酒 168ml*2 瓶 24.8 元

題目連結 https://www.luogu.com.cn/problem/P3367

並:合併

查:查詢

集:集合

並查集:用來檢查一個圖是否存在環


 

parent[i]表示i結點的父節點

rankp[i]記錄深度,表示i所在的層數。避免一條長鏈式的結構導致查詢路徑時非常慢,可以引用rankp陣列對此優化。


 

放AC程式碼:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 long long n,m;
 4 int z,x,y;
 5 int parent[20010];
 6 int rankp[20010];
 7 
 8 //找父節點
9 inline int Getparent(int o) 10 { 11 if(parent[o]==o) return o; 12 else return parent[o]=Getparent(parent[o]);//路徑壓縮 13 } 14 15 //合併 16 inline int Union(int x,int y,int parent[],int rankp[]) 17 { 18 int x_root=Getparent(x); 19 int y_root=Getparent(y); 20 if(x_root==y_root) return 0;
21 else//優化部分 22 { 23 if(rankp[x_root]>rankp[y_root]) 24 parent[y_root]=x_root; 25 else if(rankp[y_root]>rankp[x_root]) 26 parent[x_root]=y_root; 27 else 28 { 29 parent[x_root]=y_root; 30 rankp[y_root]++; 31 }
32 return 1; 33 } 34 } 35 36 //是否在同一子集 37 inline void Find(int x,int y) 38 { 39 int x_root=Getparent(x); 40 int y_root=Getparent(y); 41 if(x_root==y_root) cout<<"Y"<<endl; 42 else cout<<"N"<<endl; 43 } 44 45 int main() 46 { 47 ios::sync_with_stdio(false); 48 memset(rankp,0,sizeof(rankp)); 49 cin>>n>>m; 50 for(register int i=1;i<=n;i++) 51 parent[i]=i; 52 for(register int i=1; i<=m; i++) 53 { 54 cin>>z>>x>>y; 55 if(z==1) Union(x,y,parent,rankp); 56 else Find(x,y); 57 } 58 return 0; 59 }