只需离线反向维护并查集,建立被摧毁的边,并更新答案……
[JSOI2008]星球大战starwar C++代码实现:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 400010
#define M 200010
int n,m;
int head[N],to[2*M],next[2*M],cnt;
int f[N],t[N],v[N],ans[N];
void add(int x,int y)
{
to[++cnt]=y;
next[cnt]=head[x];
head[x]=cnt;
}
int find(int x)
{
return x==f[x]?x:f[x]=find(f[x]);
}
int main()
{
cin>>n>>m;
for(int x,y,i=1;i<=m;i++)
scanf("%d%d",&x,&y),
add(x+1,y+1),add(y+1,x+1);
cin>>t[0];
for(int i=1;i<=t[0];i++)
scanf("%d",&t[i]),
v[++t[i]]=1;
for(int i=1;i<=n;i++)
f[i]=i;
ans[t[0]+1]=n-t[0];
for(int i=1;i<=n;i++)
if(!v[i])
for(int j=head[i];j;j=next[j])
if(!v[to[j]])
{ int fx=find(i),fy=find(to[j]); if(fx!=fy) f[fx]=fy,ans[t[0]+1]--; }
for(int i=t[0];i;i--)
{
v[t[i]]=0;ans[i]=ans[i+1]+1;
for(int j=head[t[i]];j;j=next[j])
if(!v[to[j]])
{ int fx=find(t[i]),fy=find(to[j]); if(fx!=fy) f[fx]=fy,ans[i]--; }
}
for(int i=1;i<=t[0]+1;i++)
printf("%d\n",ans[i]);
}