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

2022-02-27 09:02:22 字數 1336 閱讀 9237

傳送門

總算有自己的\(bzoj\)賬號啦!

話說這題好像\(scape\)去年暑假就講過……然而我到現在才會……

\(lct\)什麼的跑得太慢了而且我也不會,所以這裡是乙個並查集的做法

首先題目意思就是要我們動態維護點雙

我們離線,先求出乙個森林,並且要使用編號盡量小的邊

連上一條邊的時候,如果它們還沒有聯通,那麼顯然答案是\(no\)

如果已經聯通,那麼它們這棵樹的路徑上所有點都會被縮排同乙個點雙里。暴力的話複雜度顯然**

我們另外開乙個並查集\(ga\),表示\(i\)所在的邊雙中深度最小的點,那麼每次路徑縮點的時候只要改所有邊雙的深度最小點就可以了

//minamoto

#include#define r register

#define fp(i,a,b) for(r int i=(a),i=(b)+1;ii;--i)

#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)

using namespace std;

char buf[1<<21],*p1=buf,*p2=buf;

inline char getc()

int read()

char sr[1<<21],z[20];int k=-1,z=0;

inline void ot()

void print(r int x)

const int n=5e5+5;

struct ege[n<<1];int head[n],tot;

inline void add(r int u,r int v),head[u]=tot;}

struct egst[n];

int fa[n],ga[n],sz[n],dep[n],q[n];

int n,m,p;

int find(int x)

void bfs(int u)

}void merge(int u,int v)

}int main()

fp(i,1,n)if(!dep[i])bfs(i);

fp(i,1,n)sz[i]=1,ga[i]=i;

fp(i,1,m)if(!st[i].is)merge(st[i].u,st[i].v);

fp(i,m+1,m+p)if(st[i].is)sr[++k]='n',sr[++k]='o',sr[++k]='\n';

else merge(st[i].u,st[i].v),print(sz[find(st[i].u)]);

return ot(),0;

}

bzoj4998 星球聯盟

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

BZOJ 4998 星球聯盟

題意 給一張無向圖,並不斷加邊 u,v 並詢問 u,v 是否位於同乙個雙聯通分量裡,若位於同一雙聯通分量,輸出這個雙聯通分量的 size 使用並查集 lct維護。有兩套並查集 s1是用來維護每個點歸屬哪乙個強連通分量,每個點的祖先是這個強連通分量的代表節點,同時代表節點儲存這個強連通分量的 size...

bzoj4998 LCT 並查集 星球聯盟

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