可持久化並查集
阿新 • • 發佈:2017-11-18
比較 root urn amp down truct 表示 void roo
如果不采用路徑壓縮而只采用按秩合並,那麽並查集的可持久化是比較容易實現的。按秩合並可以保證一棵 $n$ 個節點的樹的高度是 $O(\log n)$ 的。
實現方法:
用 $r_v$ 表示 $v$ 所在子樹的根。
假設要將點 $u$ 和點 $v$ 所在子樹和並(也就是將邊 $(u,v)$ 加入圖中),那麽需要在合並之前記錄一下 $r_u, \mathrm{rank}(r_u)$ 和 $r_v, \mathrm{rank}(r_v)$。
要恢復到某個歷史版本,就按與加邊相反的順序刪邊。
const int N = 5e5 + 5;
int par[N];
int rk[N];
int root(int x){
while(x != par[x]) x = par[x];
return x;
}
struct his{
int u, rk1;
int v, rk2;
};
his unite(int x, int y){
x = root(x);
y = root(y);
his res = {x, rk[x], y, rk[y]};
if(x == y) return res;
if(rk[x] > rk[y])
par[y] = x;
else{
par[x] = y;
if (rk[x] == rk[y])
++rk[y];
}
return res;
}
void divide(const his &x){
par[x.u] = x.u;
par[x.v] = x.v;
rk[x.u] = x.rk1;
rk[x.v] = x.rk2;
}
可持久化並查集