洛谷P1197 JSOI2008 星球大戰

2021-08-28 11:23:22 字數 1157 閱讀 4619

題目傳送門

這道題大部分的人一開始的思路都是乙個乙個的刪除點再求聯通塊數,但問題是斷開一條邊並不意味著會有乙個聯通塊斷成兩個,所以我們只能遍歷整個圖,而這個做法的時間複雜度是我們接受不了的。

既然刪點行不通,我們不妨逆向思考,從最後的狀態開始加點,這樣只需要用並查集維護聯通,然後每次遍歷加入的點的連邊就行了。如果新加入的點有將兩個原來不相連的聯通塊連線起來的邊,那麼聯通塊的數量就會減少。

上**

#include

#include

using

namespace std;

const

int n=

200010

;int h[n<<1]

,to[n<<1]

,pre[n<<1]

;//鄰接表

int n,m,q,top,fa[n<<1]

,d[n<<1]

,ans[n<<1]

;//fa記錄並查集,d按順序記錄被摧毀的星球編號,ans[i]記錄摧毀了i個星球後聯通塊數量

bool vis[n<<1]

;//記錄當前時刻每個星球是否被摧毀,為true則為被摧毀

intread()

//快讀

inline

void

ins(

int u,

int v)

//插入邊

intsfind

(int x)

//詢問並查集

intmain()

q=read()

;ans[q]

=n-q;

//在摧毀q顆星球後最多會有(n-q)個聯通塊

for(

int i=

1;i<=q;i++

)//記錄被摧毀的星球

for(

int i=

0;i)//找到最後時刻的聯通塊數量

}for

(int i=q;i>

0;i--

)//倒序計算每個星球被摧毀後的聯通塊數量

}for

(int i=

0;i<=q;i++

)printf

("%d\n"

,ans[i]);

return0;

}

洛谷 P1197 JSOI2008 星球大戰

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

洛谷P1197 JSOI2008 星球大戰

思路 首先動態求割點會tle,考慮倒序離線操作。當所有打擊完成後,tarjin統計同一連通分量上的點,並查集維護連通性 實際上來說只要兩點之間有邊則將之合併即可tarjin處理麻煩反而會mle?不清楚為什麼 再依次將被毀滅的星球復原,則對答案的影響只與當前星球連線的星球數量 及連通關係 有關,每次統...

洛谷P1197 JSOI2008 星球大戰

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