【2018夏令营】【普及】第一天基本数据结构
1、并查集的模板 (有路径压缩, 没有合并的优化)
P3367 【模板】并查集
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 6 using namespace std; 7 8 int fa[10005]; 9 10 void init(int n) { 11 memset(fa, 0, sizeof(fa)); 12 for (int i = 1; i <= n; ++i) { 13 fa[i] = i; 14 } 15 } 16 17 int find(int x) { 18 return fa[x] == x ? x : fa[x] = find(fa[x]); 19 } 20 21 void unionSet (int x, int y) { 22 x = find(x); 23 y = find(y); 24 if (x == y) { 25 return ; 26 } 27 fa[x] = y; 28 } 29 30 int main() { 31 int n, m; 32 cin >> n >> m; 33 init(n); 34 for (int i = 0; i < m; ++i) { 35 int opt, x, y; 36 cin >> opt >> x >>y; 37 if (opt == 1) { 38 unionSet(x, y); 39 } else if (opt == 2) { 40 char ans = find(x) == find(y) ? 'Y' : 'N'; 41 cout << ans << endl; 42 } else { 43 44 } 45 } 46 return 0; 47 }
P1551 亲戚
https://www.luogu.org/problemnew/show/P1551
给定一堆人,给出亲戚关系,然后q个询问,问任意两个人是否是亲戚关系 (还是裸的并查集)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 //#include <> 4 using namespace std; 5 6 int fa[6000]; 7 8 void initUnionSet(int n) { 9 for(int i = 0; i <= n; ++i) { 10 fa[i] = i; 11 } 12 } 13 14 //查询做了路径压缩 15 int find(int x) { 16 return x == fa[x] ? x : fa[x] = find(fa[x]); 17 } 18 19 //合并没有做优化,暴力合并 20 void unionSet(int x, int y) { 21 int xx = find(x); 22 int yy = find(y); 23 if (xx == yy) { return; } 24 fa[xx] = yy; 25 } 26 27 int main() { 28 int n, m, p; 29 scanf("%d %d %d", &n, &m, &p); 30 initUnionSet(n); 31 for (int i = 0; i < m; ++i) { 32 int x, y; 33 scanf("%d %d", &x, &y); 34 unionSet(x, y); 35 } 36 for (int i = 0; i < p ; ++i) { 37 int x, y; 38 scanf("%d %d", &x, &y); 39 string answer = find(x) == find(y) ? "Yes" : "No"; 40 printf("%s\n", answer.c_str()); 41 } 42 return 0; 43 }