NewCodeTemplate

This commit is contained in:
e2hang
2025-12-16 20:36:27 +08:00
parent 684e35b210
commit 8253f2dcbc
26 changed files with 2547 additions and 0 deletions

94
模板/树/并查集.cpp Normal file
View File

@@ -0,0 +1,94 @@
#include <iostream>
#include <vector>
using namespace std;
/*
并查集Disjoint Set Union
支持:
- 路径压缩
- 按集合大小合并
*/
struct DSU {
vector<int> parent; // parent[x]x 的父节点
vector<int> sz; // sz[x]:以 x 为根的集合大小
int components; // 当前连通分量个数(可选)
// 构造函数:初始化 n 个元素(编号 0 ~ n-1
DSU(int n = 0) {
init(n);
}
// 初始化
void init(int n) {
parent.resize(n);
sz.assign(n, 1);
components = n;
for (int i = 0; i < n; i++) {
parent[i] = i; // 初始时,每个节点都是自己的父节点
}
}
// 查找 x 的根(带路径压缩)
int find(int x) {
if (parent[x] != x) {
parent[x] = find(parent[x]); // 路径压缩
}
return parent[x];
}
// 合并 x 和 y 所在的集合
// 如果本来就在同一集合,返回 false
bool unite(int x, int y) {
int rx = find(x);
int ry = find(y);
if (rx == ry) return false;
// 按集合大小合并:小的挂到大的
if (sz[rx] < sz[ry]) {
swap(rx, ry);
}
parent[ry] = rx;
sz[rx] += sz[ry];
components--; // 连通分量减少
return true;
}
// 判断 x 和 y 是否在同一集合
bool same(int x, int y) {
return find(x) == find(y);
}
// 返回 x 所在集合的大小
int size(int x) {
return sz[find(x)];
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
cin >> n >> m;
DSU dsu(n);
/*
示例:
m 次操作,每次合并两个点
*/
for (int i = 0; i < m; i++) {
int a, b;
cin >> a >> b;
dsu.unite(a, b);
}
cout << dsu.components << '\n';
return 0;
}