BZOJ 4998 星球聯盟

2022-03-30 06:42:53 字數 1313 閱讀 6790

題意:給一張無向圖,並不斷加邊 \((u,v)\),並詢問 \(u,v\) 是否位於同乙個雙聯通分量裡,若位於同一雙聯通分量,輸出這個雙聯通分量的 \(size\)

使用並查集+lct維護。

有兩套並查集:s1是用來維護每個點歸屬哪乙個強連通分量,每個點的祖先是這個強連通分量的代表節點,同時代表節點儲存這個強連通分量的 \(size\);s2是用來維護原始圖的聯通性的。

注意加邊時 \((u,v)\) ,我們都是對兩個點所在聯通分量的代表節點進行操作。

我們加邊 \((u,v)\) 時,首先若兩個點所在的聯通分量的代表節點本來不連通,那直接加邊(指同時修改s2和 lct)即可。

若原來兩個點所在的聯通分量的代表節點聯通,那麼我們split(u,v),將這條鏈(當然鏈上的點可能是乙個聯通分量)的所有點縮成乙個點,我們把所有遍歷到的點的s1都指向 \(u\) ,使 \(u\) 作為新聯通分量的代表節點。

#include#define r register int

using namespace std;

namespace luitaryi const int n=200010;

int n,m,q,fa[n],ch[n][2],sz[n],stk[n],sum,cur; bool tg[n];

struct ufs

inline int f(int x)

}s1,s2;

#define ls(x) (ch[x][0])

#define rs(x) (ch[x][1])

#define rev(x) (swap(ls(x),rs(x)),tg[x]^=1)

inline bool isroot(int x)

inline void spread(int x)

inline void rot(int x)

inline void splay(int x)

}inline void acc(int x)

inline void mrt(int x)

inline void split(int x,int y)

inline void link(int x,int y)

inline void dfs(int x)

inline void add(int x,int y) else s2.fa[fx]=fy,link(x,y);

}inline void main()

}} signed main()

bzoj4998 星球聯盟

description 在遙遠的s星系中一共有n個星球,編號為1 n。其中的一些星球決定組成聯盟,以方便相互間的交流。但是,組成 聯盟的首要條件就是交通條件。初始時,在這n個星球間有m條太空隧道。每條太空隧道連線兩個星球,使得它們能 夠相互到達。若兩個星球屬於同乙個聯盟,則必須存在一條環形線路經過這...

bzoj4998 星球聯盟(並查集 邊雙)

傳送門 總算有自己的 bzoj 賬號啦!話說這題好像 scape 去年暑假就講過 然而我到現在才會 lct 什麼的跑得太慢了而且我也不會,所以這裡是乙個並查集的做法 首先題目意思就是要我們動態維護點雙 我們離線,先求出乙個森林,並且要使用編號盡量小的邊 連上一條邊的時候,如果它們還沒有聯通,那麼顯然...

bzoj4998 LCT 並查集 星球聯盟

description 在遙遠的s星系中一共有n個星球,編號為1 n。其中的一些星球決定組成聯盟,以方便相互間的交流。但是,組成 聯盟的首要條件就是交通條件。初始時,在這n個星球間有m條太空隧道。每條太空隧道連線兩個星球,使得它們能 夠相互到達。若兩個星球屬於同乙個聯盟,則必須存在一條環形線路經過這...