P1197 JSOI2008 星球大戰

2022-05-20 03:06:10 字數 1190 閱讀 1608

傳送門

並查集資料較大

直接用tarjan求聯通塊會超時

注意到只有刪除沒有新增

如果是只有新增就很容易用並查集求聯通塊

所以考慮把過程反過來

即一開始是沒有邊的

然後逐漸新增邊

把聯通塊數量存起來

再輸出就好了..

一開始先遍歷一遍最終狀態,求出聯通塊數量

然後慢慢加邊,存一下答案

順便注意一下點的編號是從0~n-1

#include#include

#include

#include

#include

using

namespace

std;

inline

intread()

while(ch>='

0'&&ch<='9'

)

return x*f;

}const

int n=400007

;int cnt,fir[n],from

[n],to[n];

inline

void add(int a,int

b)//鏈式前向星存邊

intn,m,k;

intfa[n],ans[n],del[n],sum;

//ans存答案,del[i]存第i次刪除的點,sum記錄目前有幾個聯通塊

//ans[i]指的是第i個點刪除後的聯通塊數量bool

pd[n],vis[n];

//pd判斷是否有被刪除.

//vis[i]判斷是否遍歷過點i

inline

int find(int x)//找聯通塊

inline

void dfs(int x,int

f)//遍歷最終狀態的聯通塊,f是上乙個節點

}int

main()

cin>>k;

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

for(int i=0;i)//注意是從0到n-1

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

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

printf(

"%d\n

",ans[i]);//輸出答案

return0;

}

P1197 JSOI2008 星球大戰

思路和關閉農場差不多,不過加了一些時間上的優化。當我們加入乙個點時,先假設又加入乙個單獨的連通塊,然後再掃一下與它相連的點如果在圖中但是與它不在乙個聯通塊中,那麼就將其合併,連通塊個數減一。注 並查集的題果斷找祖宗。include include include include define n 4...

P1197 JSOI2008 星球大戰

題目 p1197 jsoi2008 星球大戰 分析 看完題目,第一眼就是想到,我們反過來不斷把新的邊加入,然後利用陣列儲存答案,最後逆序輸出。num 陣列用來給破壞的星球編號 從大到小 為什麼要編號呢?因為後面 sort 排序是根據這個編號來的。預處理時,我們以兩個星球中 x,y 最大值作為該邊的編...

P1197 JSOI2008 星球大戰

很久以前,在乙個遙遠的星系,乙個黑暗的帝國靠著它的超級 統治者整個星系。某一天,憑著乙個偶然的機遇,一支反抗軍摧毀了帝國的超級 並攻下了星系中幾乎所有的星球。這些星球通過特殊的以太隧道互相直接或間接地連線。但好景不長,很快帝國又重新造出了他的超級 憑藉這超級 的力量,帝國開始有計畫地摧毀反抗軍占領的...