JZOJ3875 星球聯盟 alliance

2021-07-26 06:58:15 字數 1348 閱讀 7620

在遙遠的s星系中一共有n個星球,編號為1…n。其中的一些星球決定組成聯盟,以方便相互間的交流。

但是,組成聯盟的首要條件就是交通條件。初始時,在這n個星球間有m條太空隧道。每條太空隧道連線兩個星球,使得它們能夠相互到達。若兩個星球屬於同乙個聯盟,則必須存在一條環形線路經過這兩個星球,即兩個星球間存在兩條沒有公共隧道的路徑。

為了壯大聯盟的隊伍,這些星球將建設p條新的太空隧道。這p條新隧道將按順序依次建成。一條新軌道建成後,可能會使一些星球屬於同乙個聯盟。你的任務是計算出,在一條新隧道建設完畢後,判斷這條新軌道連線的兩個星球是否屬於同乙個聯盟,如果屬於同乙個聯盟就計算出這個聯盟中有多少個星球。

兩個星球同屬於乙個聯盟,等於它們之間本來有樹邊相連,然後再給它們直接或間接連上一條邊。

於是這題我們將初始邊和詢問邊的樹邊加進去構成樹或森林,對於詢問的邊是樹邊的就輸出no。這個可以用tarjan縮環或者用並查集實現。

對於這棵樹(或森林),我們求出深度,然後對於每個非樹邊,加入它相當於邊的兩個端點之間路徑的所有點都能屬於乙個聯盟。於是並查集縮點即可。

那麼對於一條邊的查詢,就是查詢兩個端點所在並查集的大小。

#include

#include

#include

#include

#define fo(i,j,k) for(int i=j;i<=k;i++)

#define fd(i,j,k) for(int i=j;i>=k;i--)

#define rep(i,x) for(int i=ls[x];i;i=nx[i])

#define n 200010

#define m 400010

using

namespace

std;

int to[m],nx[m],ls[n],num=0;

struct nodeb[n*2];

int tot=0;

int f[n],d[n],sz[n],fa[n];

bool bz[n];

void link(int x,int y)

int find(int x)

int dl[n];

void bfs(int s)

}}int lca(int u,int v)

int main()

}fo(i,1,n)

if(!bz[i]) d[i]=1,bfs(i);

memset(f,0,sizeof(f));

fo(i,1,n) f[i]=i;

fo(i,1,m)

if(!b[i].tr) lca(b[i].x,b[i].y);

fo(i,m+1,m+p)

}

JZOJ 3875 星球聯盟

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

置頂 星球聯盟

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

bzoj4998 星球聯盟

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