4998 星球聯盟 LCT 並查集

2021-08-16 07:24:35 字數 1627 閱讀 6424

description

在遙遠的s星系中一共有n個星球,編號為1…n。其中的一些星球決定組成聯盟,以方便相互間的交流。但是,組成聯盟的首要條件就是交通條件。初始時,在這n個星球間有m條太空隧道。每條太空隧道連線兩個星球,使得它們能夠相互到達。若兩個星球屬於同乙個聯盟,則必須存在一條環形線路經過這兩個星球,即兩個星球間存在兩條沒有公共隧道的路徑。為了壯大聯盟的隊伍,這些星球將建設p條新的太空隧道。這p條新隧道將按順序依次建成。一條新軌道建成後,可能會使一些星球屬於同乙個聯盟。你的任務是計算出,在一條新隧道建設完畢後,判斷這條新軌道連線的兩個星球是否屬於同乙個聯盟,如果屬於同乙個聯盟就計算出這個聯盟中有多少個星球。

這道題也很強啊,像我這樣的蒟蒻就只會判no……思路大概是這樣的:f[

0][x

] f[0

][x]

表示x x

所在的連通塊是什麼(就是並查集的東西),f[

1][x

]' role="presentation" style="position: relative;">f[1

][x]

f[1]

[x]表示

x x

實際上代表的是哪乙個點,然後對於每次連邊,若不在同乙個連通塊,那顯然輸出no就可以了,然後在lct上連邊;否則就把兩點間的點都縮為乙個點,具體的方法是暴力搞……但是由於每個點只會被縮一次,所以時間複雜度是***的。

#include

using

namespace

std;

#define ll long long

#define pa pair

const

int maxn=200010;

const

int inf=2147483647;

int read()

while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();

return x*f;

}int n,m,p;

int f[2][maxn];//f[0]為並查集關係 f[1]為這個點實際上是什麼點

int findfa(int o,int x)

int fa[maxn],son[maxn][2],rev[maxn],size[maxn];

void down(int x)

}bool is(int x)

void rotate(int x)

int sta[maxn],top;

void update(int x)

void splay(int x)

}void access(int x)

}void make_root(int x)

void split(int x,int y)

void link(int x,int y)

void dfs(int x,int rt)

void link(int x,int y,int type)

split(x,y);

dfs(y,y);

son[y][0]=son[y][1]=0;

if(type)printf("%d\n",size[y]);

}int main()

bzoj4998 LCT 並查集 星球聯盟

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

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

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

bzoj4998 星球聯盟

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