1. 程式人生 > >可持久化並查集

可持久化並查集

比較 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; }

可持久化並查集