#define N 100005
int st[N];
void uf_init() {
memset(st, -1, sizeof(st));
}
int uf_find(int x) {
return st[x]<0 ? x : st[x] = uf_find(st[x]);
}
void uf_union(int x, int y) {
int fx = uf_find(x), fy = uf_find(y);
if (fx != fy) {
st[fx] += st[fy];
st[fy] = fx;
}
}
千万注意初始化。
using ll = long long;
struct Dsu {
vector<ll> fa;
Dsu(int sz) : fa(sz, -1){}
int find(int u) {
return fa[u] < 0 ? u : fa[u] = find(fa[u]); // 路径压缩
}
void unite(int u, int v) {
int fu = find(u), fv = find(v);
if (fu != fv) {
// 小集合fu 加入到 大集合fv,按秩归并
if (fa[fu] < fa[fv]) swap(fu, fv);
fa[fv] += fa[fu];
fa[fu] = fv;
}
}
};
struct Wdsu {
vector<ll> fa, wt;
Wdsu(int sz) : fa(sz, -1), wt(sz, 0) {}
int find(int u) {
if (fa[u] < 0)
return u;
int v = find(fa[u]);
wt[u] += wt[fa[u]];
return fa[u] = v;
}
// 尝试u和v纳入同一集合,当路径权值冲突返回false
/*
u --val--> v
u --wt[u]--> fu
v --wt[v]--> fv
fu == fv
u --val--> v --wt[v]--> fv
val + wt[v] = wt[u]
fu !=fv
fu --(val+wt[v]-wt[u])--> fv
*/
int unite(int u, int v, int val) {
int fu = find(u), fv = find(v);
if (fu == fv) {
return wt[u] == val + wt[v];
}
fa[fu] = fv;
wt[fu] = val + wt[v] - wt[u];
return true;
}
};