又双叒叕被自己坑了...

BZOJ数据有点毒瘤,建议自己卡卡常,不过Luogu上很轻松的跑过了

 

还是比较简单的一题...

正向删点很难,所以我们考虑反着来,咱往里面加点

要注意的是,那些还没加进去的点是不算连通块个数的...不过估计就我这种rui zhi注意就够了

 

 

 1 #include<cstdio>
 2 #include<queue>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<vector>
 6 #include<algorithm>
 7 using namespace std;
 8 inline int read(){
 9     int ans=0,f=1;char chr=getchar();
10     while(!isdigit(chr)){if(chr=='-') f=-1;chr=getchar();}
11     while(isdigit(chr)){ans=(ans<<3)+(ans<<1)+chr-48;chr=getchar();}
12     return ans*f;
13 }int n,m,fa[2000005],k,vis[2000005],p[2000005],ANS[2000005];
14 vector<int> v[2000005];
15 int find(int x){if(fa[x]==x) return x;return fa[x]=find(fa[x]);}
16 int main(){
17     n=read();m=read();
18     for(int i=1;i<=n+1;i++) fa[i]=i;
19     for(int i=1;i<=m;i++){
20         int x=read(),y=read();++x,++y;
21         v[x].push_back(y);v[y].push_back(x);
22     }k=read();
23     for(int i=1;i<=k;i++) p[k-i+1]=read(),++p[k-i+1],vis[p[k-i+1]]=1;
24     for(int i=1;i<=n;i++)if(!vis[i])
25             for(int j=0;j<v[i].size();j++){
26                 if(vis[v[i][j]]) continue;
27                 int fx=find(i),fy=find(v[i][j]);
28                 if(fx!=fy) fa[fx]=fy;
29             }
30     for(int i=1;i<=n;i++) if(!vis[i]&&fa[i]==i) ANS[1]++;
31     for(int i=1,t;i<=k;i++){t=ANS[i];
32         vis[p[i]]=0;
33         for(int j=0;j<v[p[i]].size();j++){
34             if(vis[v[p[i]][j]]) continue;
35             int fx=find(p[i]),fy=find(v[p[i]][j]);
36             if(fx!=fy) fa[fx]=fy,--t;
37         }ANS[i+1]=t+1;
38     }reverse(ANS+1,ANS+k+2);
39     for(int i=1;i<=k+1;i++)    cout<<ANS[i]<<endl;
40     return 0;
41 }