makeSet(x):初始化,每個元素自成一集,父指針指向自己。find(x):尋找集合代表元(根),路徑壓縮優化:if (p[x]!=x) p[x]=find(p[x]); return p[x];union(x,y):合併兩集合,找根後掛接。維護 rank[x] 近似樹高。合併時將秩小的樹掛到秩大的樹下;秩相等任掛一邊,被掛樹根秩 +1。
int rank[MAXN];
void makeSet(int n) { for(i=0;irank[y]) p[y]=x;
else { p[x]=y; if(rank[x]==rank[y]) rank[y]++; }
}
應用例:HDU 1325 判斷是否為樹(檢查連通性、無環、入度)。
根節點存儲負的集合大小(p[root] = -size)。合併時將小集合併入大集合,更新大小。
int p[MAXN];
void makeSet(int n) { for(i=0;i
應用例:HDU 1856 最大朋友圈(求最大集合大小)。
int find(int x) {
int root = x;
while (p[root] >= 0) root = p[root];
while (x != root) { int tmp = p[x]; p[x] = root; x = tmp; }
return root;
}
struct DSU {
vector p, sz;
DSU(int n=0) { init(n); }
void init(int n) { p.resize(n); sz.assign(n,1); iota(p.begin(), p.end(), 0); }
int find(int x) { return p[x]==x?x:p[x]=find(p[x]); }
bool unite(int a, int b) {
a=find(a); b=find(b); if(a==b) return false;
if(sz[a]