置頂 星球聯盟

2022-05-08 02:27:08 字數 3807 閱讀 4404

【問題描述】

在遙遠的 s 星系中一共有 n 個星球,編號為 1…n。其中的一些星球決定組成聯盟,

以方便相互間的交流。

但是,組成聯盟的首要條件就是交通條件。初始時,在這 n 個星球間有 m 條太空

隧道。每條太空隧道連線兩個星球,使得它們能夠相互到達。若兩個星球屬於同乙個聯

盟,則必須存在一條環形線路經過這兩個星球,即兩個星球間存在兩條沒有公共隧道的

路徑。

為了壯大聯盟的隊伍,這些星球將建設 p 條新的太空隧道。這 p 條新隧道將按順序

依次建成。一條新軌道建成後,可能會使一些星球屬於同乙個聯盟。你的任務是計算出,

在一條新隧道建設完畢後,判斷這條新軌道連線的兩個星球是否屬於同乙個聯盟,如果

屬於同乙個聯盟就計算出這個聯盟中有多少個星球。

【輸入格式】

第 1 行三個整數 n,m 和 p,分別表示總星球數,初始時太空隧道的數目和即將建

設的軌道數目。

第 2 至第 m+1 行,每行兩個整數,表示初始時的每條太空隧道連線的兩個星球編

號。 第 m+2 行至第 m+p+1 行,每行兩個整數,表示新建的太空隧道連線的兩個星球編

號。這些太空隧道按照輸入的順序依次建成。

【輸出格式】

輸出共 p 行。如果這條新的太空隧道連線的兩個星球屬於同乙個聯盟,就輸出乙個

整數,表示這兩個星球所在聯盟的星球數。如果這條新的太空隧道連線的兩個星球不屬

於同乙個聯盟,就輸出」no」(不含引號)。

【樣例 1】

alliance.in

3 2 1

1 2

1 3

2 3

alliance.out

3【樣例 2】

alliance.in

5 3 4

1 2

4 3

4 5

2 3

1 3

4 5

2 4

alliance.out

no 3 2 5

【資料範圍】

對於 10%的資料有 1≤n,m,p≤100;

對於 40%的資料有 1≤n,m,p≤2000;

對於 100%的資料有 1≤n,m,p≤200000。

【題解】

演算法一:暴力列舉

對於每乙個詢問我們可以列舉每一條邊,去掉後判斷點對之間的連通性即可。

時間複雜度:o(n(m+p)2)

期望得分:10 分

演算法二:樸素的強連通分量

很明顯對於每乙個詢問,我們可以計算當前圖的強連通分量,加以判斷。使用時間複雜度均為 o(n) kosaraju 或 tarjan 演算法。

時間複雜度:o(n(m+p))

期望得分:40 分

演算法三:模型的轉換與多種圖論演算法的綜合運用

每一次都計算強連通分量顯然不合適,這樣會連帶計算出很多我們不需要的連通分量,我們要做的就是對新加的邊的兩個端點進行分析。很明顯,如果這兩個點已經處於同乙個強連通分量中,就不必改變,如果這兩個點不在同乙個強連通分量中,可能有兩種情況:

1、這條邊使得那兩個點處於同一強連通分量中。

2、這條邊使得兩個點聯通,即當前通的乙個橋。

對於第二種情況,可以預先處理,然而對於第一種情況又該如何處理呢?很明顯,如果這條邊使得原本不在同一強連通分量的兩個點處在了統一的強連通分量,則在新增這條邊之前這兩個點之間有且僅有唯一一條路徑相連。這讓我們想起了一種特殊的圖——樹!樹中任意的兩個節點之間有且僅有唯一一條路徑相連。那麼如何將原圖轉化為一棵樹呢?

實際上我們可以將上面所說的情況 2 的邊看作為一條樹邊,很明顯乙個包含n 個節點的圖最多含有 n-1 個橋。將這些橋預先計算出來後,我們可以構造乙個樹(或森林)。對於一棵樹,若樹上的兩個點不是父子關係,而它們之間新新增了一條邊,那麼這條邊可能形成新的強連通分量,由樹的性質,新增過新的邊之後,這兩個點和這兩個點所在路徑上所有的點一定處於乙個強連通分量之中。對於給定的兩個節點,我們可以先找到其最近公共祖先(lca),在將 lca 到這兩個點的路徑上所有的點合併為同乙個強連通分量。這裡可以用並查集維護。初始時每個節點指向自己,在合併時,將指標指向所合併的 lca。如上圖,當我們新新增紅色標出的那條邊時,可以將所有綠色的點指向 lca,也就是藍色的點。在維護並查集時,要注意並查集元素大小的累加。接下來的問題就是如何找到兩個點的最近公共祖先呢?最近公共祖先有乙個特點:它在樹中的高度 h 不大於所要查詢的那兩個節點在樹中的高度。我們可以迭代完成查詢 lca 的過程。例如:給定兩個點 x,y,我們得到這兩個點在樹中的高度,接下來如果 hx>=hy 我們就將 x 替換為它的父親(這裡的父親指縮點後的父親),否則就將 y 替換為它的父親,直到 x=y 為止。這期間,我們可以順便完成並查集的合併操作。

顯然,一開始我們還需進行對每個節點 h 的計算,這裡推薦用 bfs(dfs

可能會爆棧)更為合適。需要注意的是,給定的圖未必聯通,所以構成的可能不

是樹而是森林。

下面讓我們總結這個演算法的流程:

第一步:依據輸入資料構造出樹或森林,這裡可以用強連通分量找橋也可以選用並查集。

第二步:bfs 計算出每個節點 h 的大小。

第三步:依次處理新加的 p 條邊,維護並查集完成 lca 查詢及縮點操作。

時間複雜度:o(n+m+p)

期望得分:100 分。

涉及內容: 1.圖與樹的轉化

2.並查集、強連通分量演算法

3.寬度優先搜尋

4.資料的預處理與再處理。

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define re register

#define il inline

#define fp(i,a,b) for(re int i=a;i<=b;i++)

#define fq(i,a,b) for(re int i=a;i>=b;i--)

using

namespace

std;

const

int max=200005;

struct edge

a[max<<1];

struct solve

put[max],que[max];

int size[max],deep[max],f[max];

int head[max],tot,fa[max];

int n,m,q,cnt,qcnt,num[max];

il void add(int u,int v)

;head[u]=tot;

a[++tot]=(edge);head[v]=tot;

}il int find(int x)

il void dfs(int u,int fa)

}void union(int u,int v)

u=y;

}}il int gi()

int main()

fp(i,1,q)

fp(i,2,n)

fp(i,1,n) f[i]=i,size[i]=1;

dfs(1,0);

fp(i,1,cnt)

union(put[i].x,put[i].y);

fp(i,1,q)

if(!num[i]) printf("no\n");

else

fclose(stdin);

fclose(stdout);

return

0;}

JZOJ 3875 星球聯盟

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

bzoj4998 星球聯盟

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

BZOJ 4998 星球聯盟

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