#include<bits/stdc++.h> usingnamespace std; constint N = 50; int n, m; int fa[N];
intfind(int x){ if (fa[x] == x) return x; return fa[x] = find(fa[x]); // 顺带着压缩 } voidunionset(int x, int y){ // x 的根指向 y 的根 fa[find(x)] = find(y); }
intmain(){ cin >> n >> m; int z, x, y; for (int i = 1; i <= n; i++) fa[i] = i; while (m--) { cin >> z >> x >> y; if (z == 1) unionset(x, y); else { x = find(x), y = find(y); if (x == y) puts("Y"); elseputs("N"); } } return0; }
这个代码中当z = 1 的时候插入,等于 2 的时候查找
线段树
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#define lc p<<1 // 后续方便操作 #define rc p<<1 | 1 #define N 500005 int n, w[N]; structnode { int l, r, sum; }tr[N*4];
voidbuild(int p, int l, int r){ tr[p] = { l,r,w[l] }; if (l == r) return; int m = l + r >> 1; build(lc, l, m); build(rc, m + 1, r); tr[p].sum = tr[lc].sum + tr[rc].sum; }
1 2 3 4 5 6 7 8 9 10
voidupdate(int p, int x, int k){ if (tr[p].l == x && tr[p].r == x) { tr[p].sum += k; return; } int m = tr[p].l + tr[p].r >> 1; if (x <= m) update(lc, x, k); if (x > m) update(rc, x, k); tr[p].sum = tr[lc].sum + tr[rc].sum; }
1 2 3 4 5 6 7 8
intquery(int p, int x, int y){ // 区间查询 if (x <= tr[p].l && tr[p].r <= y) return tr[p].sum; // 能够覆盖就返回 int m = tr[p].l + tr[p].r >> 1; // 不能覆盖的话就裂开 int sum = 0; if (x <= m) sum += query(lc, x, y); if (y > m) sum += query(rc, x, y); return sum; }
voidunionn(int x, int y){ int a = find(x), b = find(y); if (a == b) return; else p[b] = a; }
intmain(){ cin >> n >> m; // 初始化 for (int i = 1; i <= n; i++) { p[i] = i; } int a, b; for (int i = 0; i < m; i++) { cin >> a >> b; unionn(min(a, b), max(a, b)); } int ans = 0; for (int i = 1; i <= n; i++) { int a = find(i); if (vis[a] == 0) { ans++; vis[a] = 1; } } cout << ans; }