问题传送门:2333
其实比较23333333333333---------------------
(看到 []山边[] 自然而然的就会倒着来减边对吧)
于是窝萌就想出了一个倒着来的方法
加边在带并查集就好了
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <windows.h>
#define rep(j,k,l) for (int j=k;j<=l;j++)
#define red(j,k,l) for (int j=k;j>=l;j--)
using namespace std;
int fa[1111111],st[1111111],to[1111111],ne[1111111],an[1111111],a[1111111],b[1111111];
int ff(int k){
if (k==fa[k]) return k;
return fa[k]=ff(fa[k]);
}
void add(int k,int l,int p){
to[p]=l;
ne[p]=st[k];
st[k]=p;
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
rep(i,1,m){
int k,l;
scanf("%d%d",&k,&l);
k++,l++;
add(k,l,2*i-1);add(l,k,2*i);
}
scanf("%d",&m);int p=0;
//while (scanf("%d",&p)!=EOF){
//while (m<6){
rep(i,1,m){
scanf("%d",&p);
p++;
b[i]=p;
a[p]=1;
}
//printf("%d\n",m);
int ans=n-m;
rep(i,1,n) fa[i]=i;
rep(i,1,n) if (a[i]==0){
int k=ff(i);
for (int j=st[i];j!=0;j=ne[j])if (a[to[j]]==0){
int l=ff(to[j]);
if (k!=l){
ans--;
fa[l]=k;
}
}
}
red(i,m,1){
//printf("%d ",ans);
an[m-i+1]=ans;
int k=ff(b[i]);
a[b[i]]=0;
for (int j=st[b[i]];j!=0;j=ne[j])if (a[to[j]]==0){
int l=ff(to[j]);
if (k!=l){
ans--;
fa[l]=k;
}
}
ans++;
}
//printf("\n");
printf("%d\n",ans);
red(i,m,1) printf("%d\n",an[i]);
system("pause");
return 0;
}