很久以前,在乙個遙遠的星系,乙個黑暗的帝國靠著它的超級**統治者整個星系。某一天,憑著乙個偶然的機遇,一支反抗軍摧毀了帝國的超級**,並攻下了星系中幾乎所有的星球。這些星球通過特殊的以太隧道互相直接或間接地連線。
但好景不長,很快帝國又重新造出了他的超級**。憑藉這超級**的力量,帝國開始有計畫地摧毀反抗軍占領的星球。由於星球的不斷被摧毀,兩個星球之間的通訊通道也開始不可靠起來。現在,反抗軍首領交給你乙個任務:給出原來兩個星球之間的以太隧道連通情況以及帝國打擊的星球順序,以盡量快的速度求出每一次打擊之後反抗軍佔據的星球的連通快的個數。(如果兩個星球可以通過現存的以太通道直接或間接地連通,則這兩個星球在同乙個連通塊中)。
輸入格式:
輸入檔案第一行包含兩個整數,n (1 <= n <= 2m) 和m (1 <= m <= 200,000),分別表示星球的數目和以太隧道的數目。星球用0~n-1的整數編號。
接下來的m行,每行包括兩個整數x, y,其中(0<=x<>y接下來一行是乙個整數k,表示帝國計畫打擊的星球個數。
接下來的k行每行乙個整數x,滿足0<=x輸出格式:
輸出檔案的第一行是開始時星球的連通塊個數。
接下來的k行,每行乙個整數,表示經過該次打擊後現存星球的連通塊個數。
輸入樣例#1:
8 130 11 6
6 55 0
0 61 2
2 33 4
4 57 1
7 27 6
3 6516
357
輸出樣例#1:
111233
[jsoi2008]
題目大意:從乙個無向圖中去掉一些點,求連通塊的個數。
知識點:貪心,並查集。
這道題有多個查詢,我們可以考慮用離線做法。這就變成了在去掉k個點的基礎下,每加乙個點連通塊的個數。
去掉k個點之後連通塊的個數最多是n-k個(每個點互不相通)。我們考慮連通塊減少的條件:
如果加入這個點這個點只屬於某乙個連通塊,那麼連通塊的個數不會減少。
如果加入這個點這個點屬於兩個連通塊,連通塊的個數-1,然後再將這兩個連通塊合併。
這樣的話逆序做一遍就行了。
#include#include#include
#include
using
namespace
std;
const
int maxn=400000+5
;inline
intread()
while(ch>='
0'&&ch<='9')
return x*f;
}int
n,m,k,num,tot;
inthead[maxn],father[maxn],a[maxn],b[maxn];
bool
vis[maxn];
struct
node
e[maxn];
inline
void add(int
from,int
to)int find(int
x)int
main()
k=read(); tot=n-k;
for(int i=1;i<=k;i++)
for(int i=1;i<=num;i=i+2)//
因為建的是雙向邊}}
b[k+1]=tot;
for(int j=k;j>=1;j--)
}//合併的時候把r2合併到r1上,這樣u的父親就不會變,減少計算
b[j]=tot;
}for(int i=1;i<=k+1;i++)
printf(
"%d\n
",b[i]);
return0;
}
洛谷 P1197 JSOI2008 星球大戰
題目描述 很久以前,在乙個遙遠的星系,乙個黑暗的帝國靠著它的超級 統治者整個星系。某一天,憑著乙個偶然的機遇,一支反抗軍摧毀了帝國的超級 並攻下了星系中幾乎所有的星球。這些星球通過特殊的以太隧道互相直接或間接地連線。但好景不長,很快帝國又重新造出了他的超級 憑藉這超級 的力量,帝國開始有計畫地摧毀反...
洛谷P1197 JSOI2008 星球大戰
思路 首先動態求割點會tle,考慮倒序離線操作。當所有打擊完成後,tarjin統計同一連通分量上的點,並查集維護連通性 實際上來說只要兩點之間有邊則將之合併即可tarjin處理麻煩反而會mle?不清楚為什麼 再依次將被毀滅的星球復原,則對答案的影響只與當前星球連線的星球數量 及連通關係 有關,每次統...
洛谷P1197 JSOI2008 星球大戰
很久以前,在乙個遙遠的星系,乙個黑暗的帝國靠著它的超級 統治者整個星系。某一天,憑著乙個偶然的機遇,一支反抗軍摧毀了帝國的超級 並攻下了星系中幾乎所有的星球。這些星球通過特殊的以太隧道互相直接或間接地連線。但好景不長,很快帝國又重新造出了他的超級 憑藉這超級 的力量,帝國開始有計畫地摧毀反抗軍占領的...