Kruskal重构树
(Kruskal重构树其实比较简单,还好写)
前置知识点
- Kruskal算法求最小/最大生成树
- 并查集
下面是一个并查集的模板。
// 结构体包装的并查集
struct Dset {
vector<int>dad;
void inti(int size) {
dad.assign(size + 1, -1);
}
int &operator [] (int i) {
return dad[i];
}
int Find(int v) {
if (dad[v] != -1) {
return dad[v] = Find(dad[v]);
}
return dad[v];
}
bool Union(int a, int b) {
a = Find(a);
b = Find(b);
if (a == b)
return false;
dad[a] = b;
return true;
}
};
此外,因为Kruskal重构树本身的性质,和LCA联系在一起也很常见。这里也放出LCA的模板。
vector<int>g[MAXN];
struct LCA {
vector<vector<int>>fa;
vector<int>lg, depth;
void inti(int size) {
fa.assign(size + 1, vector<int>(32, 0));
lg.assign(size + 1, 0);
depth.assign(size + 1, 0);
lg[2] = 1;
for (int i = 3; i < lg.size(); ++ i) {
lg[i] = lg[i >> 1] + 1;
}
}
void dfs(int now, int dad) {
depth[now] = depth[fa] + 1;
fa[now][0] = dad;
for (int i = 1; i <= n; ++ i) {
fa[a][i] = fa[fa[a][i - 1]][i - 1];
}
for (auto nex : g[now]) {
if (nex != dad) {
dfs(nex, now);
}
}