皮皮通過一次聚會認識了n個妹子。經過仔細的研究皮皮發現了乙個有趣的現象:那就是有m對妹子是互相認識的。然而如果兩個妹子直接或間接地認識(a認識b,b認識c,則a認識c),那麼皮皮就只能在這兩個妹子裡面選乙個來泡。
然而空空空空的皮皮想要泡到盡量多的妹子,於是皮皮就開始採取了一系列的行動:每次讓兩個妹子絕交。作為皮皮的路鳴澤的你需要在每次皮皮採取行動後告訴皮皮現在他最多能泡多少個妹子。
第一行兩個整數 n 和 m。
接下來 m 行每行兩個整數表示這兩個妹子互相認識。保證無重邊無自環。
接下來乙個整數q表示皮皮採取了q次行動。
接下來q行每行乙個整數x表示皮皮成功讓第x對(按輸入順序)認識的妹子絕交了。
輸出有q+1行每行乙個整數表示當前皮皮最多可以泡多少個妹子。第乙個整數表示皮皮在採取行動之前能泡多少個妹子。
對於30%的資料 n<=100,m<=200
對於60%的資料 n<=1000,m<=2000
對於100%的資料 n<=100000,m<=200000,q<=m,資料保證無兩條相同的邊。
beginend
冪萎大**
一開始往雙聯通分量想的,然後就用並查集a了;p
倒著算,每次加入原本要刪除的邊合併兩個端點。由於每次只可能少乙個集合或不變,那麼判斷一下合併前兩端點的集合是否相同就可以了
io流慢得可以
#include
#include
#define n 100001
#define m 200001
using
namespace
std;
struct edgee[m];
int bct[n],ans[m],f[n],ls[m],opt[n],maxe=0;
void add(int x,int y);ls[x]=maxe;}
int find(int x)
int merge(int x,int y)
return0;}
int main()
int m;
cin>>m;
for (int i=1;i<=m;i++)
for (int i=1;i<=maxe;i++)
if (!e[i].vis)
merge(e[i].x,e[i].y);
int t=0;
for (int i=1;i<=n;i++)
if (!bct[find(i)]++)
t++;
memset(bct,0,sizeof(bct));
int v=0;
for (int i=1;i<=n;i++)
if (!bct[find(i)]++)
v++;
for (int i=m;i>0;i--)
ans[i]=ans[i+1]+merge(e[opt[i]].x,e[opt[i]].y);
for (int i=1;i<=m;i++)
cout
0;}
並查集 家族 (ssl 1896)
合併一些集合,然後判斷某兩個點是否在同乙個集合內 若某個家族人員過於龐大,要判斷兩個是否是親戚,確實還很不容易,現在給出某個親戚關係圖,求任意給出的兩個人是否具有親戚關係。規定 x和y是親戚,y和z是親戚,那麼x和z也是親戚。如果x,y是親戚,那麼x的親戚都是y的親戚,y的親戚也都是x的親戚。第一行...
家譜 SSL 2343 並查集
time limit 10000ms memory limit 65536k total submit 88 accepted 43 case time limit 1000ms description 現代的人對於本家族血統越來越感興趣,現在給出充足的父子關係,請你編寫程式找到 某個人的最早的祖先...
ssl1312 旅行 並查集
z小鎮是乙個景色宜人的地方,吸引來自各地的觀光客來此旅遊觀光。z小鎮附近共有n個景點 編號為1,2,3,n 這些景點被m條道路連線著,所有道路都是雙向的,兩個景點之間可能有多條道路。也許是為了保護該地的旅遊資源,z小鎮有個奇怪的規定,就是對於一條給定的公路ri,任何在該公路上行駛的車輛速度必須為vi...