C City 逆向並查集

2022-05-03 14:27:28 字數 1993 閱讀 9006

時間限制: 1 s      記憶體限制: 128 mb     

如果城市a和城市b互通,城市b和城市c互通,那麼城市a和城市c也互通,a、b、c三個城市算乙個聚集點。先已知有n個城市和m條道路,想求的是有幾個聚集點?但小s覺得太簡單了,由於戰爭原因,某些城市會被飛彈銷毀掉,與之相應的道路也變得不可用。之前已經被銷毀的不會被復原。現給定每次銷毀的城市順序,求每次銷毀後聚集點有多少個。

第一行輸入n

'>n

和m'>m

,表示城市數量和道路數量(1≤

n≤104

,1≤m

≤2n)

'>(1≤n≤104,1≤m≤2n)

接下來m

'>m

m'>(1≤

n≤104

,1≤m

≤2n)

'>行,每行輸入兩個數a

i'>ai和bi

'>bi (1

≤ai,

bi≤n

)'>(1≤ai,bi≤n)

。表示ai和bi直接有道路第m+

2'>m+2

m'>(1≤

n≤104

,1≤m

≤2n)

'>a

i'>b

i'>(1≤

ai,b

i≤n)

'>行輸入q

'>q

,表示有q

'>q

個城市會被銷毀 (1≤

q≤n)

'>(1≤q≤n)

接下來輸入q

'>q

個數,每行輸入乙個不重複的數,表示被銷毀的城市

輸出一行q個數,每i個數表示第i個城市銷毀後聚集點的數量

8 9

1 21 3

1 62 4

3 64 5

4 75 7

5 84

3 2 5 4

1 2 3 3
#include#include

#include

#define ll long long

using

namespace

std;

int a[100005], b[100005], c[100005], p[100005], ans[100005], vis[100005], r[100005

];int n, m, t = 0

, cnt;

void init()//

初始化集合,每個元素的根節點都是自己

}int find(int x)//

查詢元素x的根節點是誰

void join(int x, int y)//

合併兩個集合

}void num()//

求不同子集個數

}bool sameroot(int x, int y)//

查詢兩個元素的老闆是否相同

intmain()

intk;

scanf("%d

", &k);

for (int i = 1; i <= k; i++)

for (int i = 1; i <= m; i++)

num();

intbase = t;//

銷毀所有c[i]元素之後可以構成幾個子集

cnt = base

; ans[k + 1] = base

;

for (int i = k; i >= 1; i--)}}

if (b[j] == c[i] && vis[a[j]] == 0

) }}

}}

for (int i = 2; i <= k + 1; i++)

printf("\n

");//system("pause");

return0;

}

相似題目:

逆向並查集

題目 題目.題意 有n個戰艦 0 n 1 每個戰艦有乙個戰鬥力,然後輸入乙個m表示m對戰艦聯合,然後輸入乙個q表示q次查詢。接下來q行有兩種輸入 1 query x 表示查詢和x戰艦聯合對戰艦中攻擊力最大的戰艦的編號 如果戰鬥力相同輸出小的編號 如果沒有就輸出 1.2 destroy x y 破壞x...

逆向並查集(ZOJ 3261)

與並查集不同,給出乙個圖中原有的一些邊,然後給出操作,操作不是向圖中新增邊,而是在已有的邊上,將邊刪除。對於該種情況,需要把首先讀入所有操作,把要求刪除的邊全部刪除,再按照從後往前的順序處理操作,這樣刪邊操作又重新轉化為了添邊的操作。例題 zoj3261 connections in galaxy ...

zoj 3261 逆向並查集

很明顯是逆向的並查集,建立邊再銷毀,思路也很巧妙的逆向思考 如果正著一一銷毀,相當於倒著一一建邊。所以儲存q次提問,最後倒著來一一建邊。在此之前先把沒有銷毀的邊全部建好 細節power能量注意一下 view code 1 include 2 include 3 include 4 include 5...