并查集模板
并查集模板题目: P3367
普通并查集模板:
初始化:
并查集数组每个元素初始自成一个集合,所以每个元素的值为其本身。所处的树的深度初始化为1
1 void init(int n) 2 { 3 for(int i = 1; i <= n; i++) 4 { 5 f[i] = i; 6 r[i] = 1; 7 } 8 }
代表元素的查找:
带有路径压缩的查找,递归写法:
1 int getfather(int x) 2 { 3 return f[x] == x?x:(f[x] = getfather(f[x])); 4 }
注意带括号,三元运算符优先级比等号高
两个集合的合并:
所处深度小的合并到深度大的
1 void mergeset(int x, int y) 2 { 3 x = getfather(x); y = getfather(y); // 注意是父节点的合并 4 if(getfather(x) != getfather(y)) 5 { 6 if(r[x] <= r[y]) f[x] = y; 7 else f[y] = x; 8 if(r[x] == r[y] && x != y) r[x]++; 9 } 10 }
整体代码(根据模板题写的):
1 #include <iostream> 2 #include <cstdio> 3 #define N 200010 4 using namespace std; 5 int f[N],r[N]; 6 void init(int n) 7 { 8 for(int i = 1; i <= n; i++) 9 { 10 f[i] = i; 11 r[i] = 1; 12 } 13 } 14 int getfather(int x) 15 { 16 return f[x] == x?x:(f[x] = getfather(f[x])); 17 } 18 void mergeset(int x, int y) 19 { 20 x = getfather(x); y = getfather(y); 21 if(getfather(x) != getfather(y)) 22 { 23 if(r[x] <= r[y]) f[x] = y; 24 else f[y] = x; 25 if(r[x] == r[y] && x != y) r[x]++; 26 } 27 } 28 int main() 29 { 30 int n,m,z,x,y; 31 cin >> n >> m; 32 init(n); 33 while(m--) 34 { 35 cin >> z >> x >> y; 36 if(z == 1) mergeset(x,y); 37 else if(z == 2) cout << (getfather(x) == getfather(y)?'Y':'N') << endl; 38 } 39 return 0; 40 }

浙公网安备 33010602011771号