NYOJ 1022合縱連橫 並查集刪除演算法

2021-06-27 10:22:40 字數 2420 閱讀 3025

合縱連橫

時間限制:

1000

ms  | 

記憶體限制:

65535kb

難度:3

描述

亂世天下,諸侯割據。每個諸侯王都有一片自己的領土。但是不是所有的諸侯王都是安分守己的,實力強大的諸侯國會設法吞併那些實力弱的,讓自己的領土面積不斷擴大。而實力弱的諸侯王為了不讓自己的領土被吞併,他會聯合一些其他同樣弱小的諸侯國,組成聯盟

(聯盟不止乙個

),來共同抵抗那些強大的諸侯國。 強大的諸侯國為了瓦解這些聯盟,派出了最優秀的間諜來離間他們,使一些諸侯國退出聯盟。最開始,每個諸侯國是乙個聯盟。

有兩種操作 1

、u x y 表示x

和y在同乙個

聯盟。(0≤x

,y) 2

、d x   表示x

退出聯盟。

輸入

多組測試資料

第一行兩個數,n和

m(1 ≤ n≤ 10^5, 1 ≤ m ≤10^5

),分別表示諸侯國的個數和操作次數。

接下來有

m行操作

輸出

輸出聯盟的個數

樣例輸入

5 7

u 0 1

u 1 2

u 0 3

d 0u 1 4

d 2u 0 2

10 1

u 0 9

樣例輸出

case #1: 2

case #2: 9

這道題一讀題,應該都能想到要用並查集歸併集合。這道需要實現並查集的刪除操作。那麼問題就來了,並查集的的結構是一顆樹,它的邊是有向且只指向父節點的。那麼刪除乙個節點(也就是讓它的父節點成為它自己),指向這個節點孩子節點的根就會丟失。學習這個演算法的時候網上說是用虛根,看了很久才看懂。

我就想用通俗更易懂的描述出來」虛根「:

例子:食品店要給顧客甲派送食物food裝在箱子box裡,box有個掛鉤(掛鉤就相當於連線父節點的邊)。food儲存箱子編號,box存父節點。

food有很多,把要送的歸在一類後。顧客甲打**退訂了某些。

如下圖,food[2]=2.編為2的food它的箱子box編號是2

box[3]=3;編號為3的箱子box它的掛鉤掛在自己上(它的父節點是它自己)。

建立如下並查集樹。box[3]=2;

然後顧客甲打**要退訂編號為4,6的food。

接下來我們只需要把編號為4的food拿走,用編號為n++(7)的箱子裝起來。

編號為4的箱子依然留在那裡,這樣就不影響編號4的box後面掛的箱子的根節點就不會喪失。

拿走6同理。

接下來又有一顧客乙要走了4,6.

box[food[6]]=food[4];\\把編號為6的food它所在的箱子8的掛鉤掛到編號為4的food它所在的箱子7上。

food 2,3,1,5歸顧客甲一類,food 4,6歸顧客乙一類。這樣雖然浪費了盒子但是歸類是正確的。搜尋x代表元,也就是通過x的箱子找到根箱子。

下附**:

#include #include int box[1000050];

int food[1000050];

bool mark[1000050];

int find(int x)

return f;

}void merge(int xx,int yy)

int main()

{ int n,m;

char ch;

int x,y;

int ans;

int count=1;

int t;

int i;

while(~scanf("%d%d",&n,&m))

{ t=n;

for(i=0;i

NYOJ 1022 合縱連橫(並查集刪除操作)

合縱連橫 時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述 亂世天下,諸侯割據。每個諸侯王都有一片自己的領土。但是不是所有的諸侯王都是安分守己的,實力強大的諸侯國會設法吞併那些實力弱的,讓自己的領土面積不斷擴大。而實力弱的諸侯王為了不讓自己的領土被吞併,他會聯合一些其他同樣弱小...

NYOJ1022合縱連橫(支援刪除操作的並查集)

時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述 亂世天下,諸侯割據。每個諸侯王都有一片自己的領土。但是不是所有的諸侯王都是安分守己的,實力強大的諸侯國會設法吞併那些實力弱的,讓自己的領土面積不斷擴大。而實力弱的諸侯王為了不讓自己的領土被吞併,他會聯合一些其他同樣弱小的諸侯國,...

合縱連橫(並查集)

描述亂世天下,諸侯割據。每個諸侯王都有一片自己的領土。但是不是所有的諸侯王都是安分守己的,實力強大的諸侯國會設法吞併那些實力弱的,讓自己的領土面積不斷擴大。而實力弱的諸侯王為了不讓自己的領土被吞併,他會聯合一些其他同樣弱小的諸侯國,組成聯盟 聯盟不止乙個 來共同抵抗那些強大的諸侯國。強大的諸侯國為了...