顺序做一定会超时
考虑逆序做
先把该删除的点全部删除
然后逆序加入图中,在加入的过程判断联通不联通;
不联通的话就让连通块的个数-1;然后把2个连通块连起来
还是比较难的
#include <bits/stdc++.h>
using namespace std;
const int N=4e5+5;
struct node{
int f,t;
int nex;
}edge[N];
int head[N];
int broken[N];
int tot=0;
int bb[N];
int root[N];
stack<int> res;
void add(int f,int t)
{
++tot;
edge[tot].f=f;
edge[tot].t=t;
edge[tot].nex=head[f];
head[f]=tot;
}
int fd(int a)
{
if(root[a]==a){
return a;
}
return root[a]=fd(root[a]);
}
void unit(int a,int b)
{
int fa=fd(a);
int fb=fd(b);
if(fa!=fb){
root[fa]=fb;
}
}
int main()
{
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++){
head[i]=-1;
root[i]=i;
}
int a,b;
for(int i=1;i<=m;i++){
cin>>a>>b;
add(a,b);
add(b,a);
}
int k;
cin>>k;
for(int i=1;i<=k;i++){
cin>>bb[i];
broken[bb[i]]=1;
}
int total=n-k;
for(int i=1;i<=tot;i++){
if(!broken[edge[i].f]&&!broken[edge[i].t]){
//cout<<"for"<<endl;
if(fd(edge[i].f)!=fd(edge[i].t)){
unit(edge[i].f,edge[i].t);
total--;
}
}
}
res.push(total);
for(int i=k;i>=1;i--){
broken[bb[i]]=0;
total++;
for(int j=head[bb[i]];j!=-1;j=edge[j].nex){
if(!broken[edge[j].t]){
if(fd(bb[i])!=fd(edge[j].t)){
// cout<<bb[i]<<"---->"<<edge[j].t<<endl;
unit(bb[i],edge[j].t);
total--;
}
}
//cout<<"=========== "<<bb[i]<<endl;
}
res.push(total);
//cout<<total<<endl;
}
while(res.size()){
int fr=res.top();
cout<<fr<<endl;
res.pop();
}
return 0;
}