並查集 黑魔法師之門

2021-06-08 16:47:33 字數 2061 閱讀 1986

黑魔法師之門

(magician.pas/c/cpp)

題目描述

的個數對1000000009取模的值。此處子圖(v, e) 定義為:點集v和邊集e都是原圖的任意子集,其中e中的邊的端點都在v中。

輸入格式

第一行包含兩個整數n和m。

接下來m行,每行兩個整數a和b,代表門控系統新增了一條無向邊(a, b)。

輸出格式

輸出一共m行,表示每次操作後的密碼。

樣例輸入

4 83 13 2

2 12 1

1 31 4

2 42 3

樣例輸出

樣例說明

第三次新增之後,存在乙個滿足條件的子圖(其中1, 2, 3是資料中邊的標號)。

第四次新增之後,存在三個子圖,,。 ……

資料範圍與約定

對於30% 的資料,n, m≤10。

對於100% 的資料,n≤200000,m≤300000。

題目中定義的子環,經過分析可以發現,它就是乙個乙個環。

我們可以求出元環個數n來,再根據排列組合求出元環組合(子圖)總數為2^n-1.

我考試的時候卡在了後面那句話上,因此就沒做出來。

即子圖總數為2^n-1,因為我以為這些環必須是有交點的。實際上不用,再仔細看一下定義,可以明白,下面這種情況,其實他的子圖個數是3而不是2。

當時我就卡在了這裡,我想找到所有有交點的環,再用排列組合來算,但是這實際上很難處理。。。都是題意沒有搞清楚的過。

多讀題,仔細理解,總會有收穫的。

和環有關的演算法,了解到並查集的優勢後,現在能夠使用的就有三個了。tarjan,floyd,並查集。(tarjan放在這裡其實是比較牽強的)

而並查集,我們只需要在加入新的邊之前,判斷是否已經在乙個聯通分量裡,如果在,增加一條邊,必定會增加乙個元環。

題解裡的思路和我的不同。順便貼上題解。

黑魔法師之門

大致思路:

實際上每次操作後的答案就是2^(圖中」元」環的個數)。

元環的意思如右圖所示,(1-2-3-4-1)和(3-4-5-3) 是元環,

1-2-3-5-4-1 不是,因為它可以看做由上述的兩個環合成。

因為乙個環裡每個點的度數都是大於零的偶數,我們可以這

樣來構造答案:每個環有選和不選兩種選擇,如果選擇了該

環,那麼環上所有邊的「選擇次數」+1。最後取所有「選擇次數」為奇數的邊構成乙個邊集,

就是乙個答案。可以證明這樣構造出來的解不重複且涵蓋了所有情況。因此答案就是2^(圖

中」元」環的個數)。實現方法非常簡單,只需要乙個並查集即可。

具體實現方法:

並查集維護連通性,初始化ans=1。

加入一條邊(x,y)時,如果x 和y 在同一集合內,ans*=2。

每次詢問輸出ans-1。

時間複雜度o(m α(n)),α(n)代表並查集的複雜度。

#include #include using std::cout;

long fa[200010];

long getroot(long l)

inline void merge(long a,long b)

long getint()

do rs=(rs<<3)+(rs<<1)+tmp-'0';

while (isdigit(tmp=getchar()));

return sgn?rs:-rs;

}int main()

else

merge(a,b);

printf("%ld\n",ans-1);

} return 0;

}

黑魔法師之門 並查集

有一張無向無權圖,求每一時刻圖中每個點的度數大於零且都是偶數的子圖的個數對1000000009取模的值。此處子圖 v,e 定義為 點集v和邊集e都是原圖的任意子集,其中e中的邊的端點都在v中。由於每一時刻都要輸出,所以dfs肯定是不行的,像 連通塊 一樣,正解是並查集。題目中圖中每個點的度數大於零且...

黑魔法師之門 magician 並查集

題目 輸入輸出 第一行包含兩個整數 n 和 m。接下來 m 行,每行兩個整數 a和 b,代表門控系統新增了一條無向邊 a,b 輸出一共 m 行,表示每次操作後的密碼。輸入樣例 4 8 3 13 2 2 12 1 1 31 4 2 42 3 輸出樣例 0 01 37715 31題意簡述 每次加邊之後輸...

黑魔法師之門

給出乙個大小為 n 的無向圖,求圖中每個點的度數大於零且都是偶數的子圖的個數。子圖不一定是聯通的!則設圖中最小環 不由其它環組成的環 的個數為 x 如果同一聯通塊中的點再次聯通,就構成了乙個新的最小環。因為這些環選與不選都可構成新子圖,於是 ans 2 x 1 去掉乙個環都不選的情況 include...