这道题如果直接做很困难,但如果我们倒过来做,此题就变成了一个可以用并查集做的题。
注意还没还原到的星球不能和当前一起处理。
#include <cstdio>
#include <vector>
using namespace std;
const int N=400005;
int n,m,num,x,y,k;
int atk[N],fa[N];
bool yes[N],in[N];
int ans[N];
int fi,fj;
vector<int> map[N];
int gf(int x)
{
return x==fa[x]?x:fa[x]=gf(fa[x]);
}
int main()
{
register int i,j;
scanf("%d %d",&n,&m);
for (i=1;i<=m;i++)
{
scanf("%d %d",&x,&y);
map[x].push_back(y);
map[y].push_back(x);
}
scanf("%d",&k);
num=n-k;
for (i=1;i<=k;i++)
{
scanf("%d",&atk[i]);
yes[atk[i]]=1;
}
for (i=0;i<n;i++)
{
fa[i]=i;
}
for (i=0;i<n;i++)
{
if (!yes[i])
{
for (j=0;j<map[i].size();j++)
{
if (in[map[i][j]])
{
fi=gf(i);
fj=gf(map[i][j]);
if (fi!=fj) num--,fa[fi]=fj;
}
}
in[i]=1;
}
}
ans[k+1]=num;
for (i=k;i>=1;i--)
{
num++;
for (j=0;j<map[atk[i]].size();j++)
{
if (in[map[atk[i]][j]])
{
fi=gf(atk[i]);
fj=gf(map[atk[i]][j]);
if (fi!=fj) num--,fa[fj]=fi;
}
}
in[atk[i]]=1;
ans[i]=num;
}
for (i=1;i<=k+1;i++)
{
printf("%d\n",ans[i]);
}
return 0;
}