The idea is actually very good to think: is backwards maintenance and check set.
However? The details are super-large.
First, each node can be attacked multiple times, just the one that started the attack.
Second, consider the dependencies of a clear and checked set.
#include <iostream>
#include <cstdio>
#include <cstring>
#define Maxe 950050
#define MAXV 950050
using namespace Std;
struct Edge
{
int v,nxt;
}e[maxe];
int G[MAXV],N,M,K,X,Y,NOW[MAXV],ANS[MAXV],CNT=0,NUME=0,FATHER[MAXV],FIRST[MAXV];
BOOL VIS[MAXV],JUDGE[MAXV];
void Addedge (int u,int v)
{
E[++nume].v=v;
E[nume].nxt=g[u];
G[u]=nume;
}
void Dfs (int x,int fath)
{
Vis[x]=true;father[x]=fath;
for (int i=g[x];i;i=e[i].nxt)
{
if ((Vis[e[i].v]==false) && (judge[e[i].v]==true))
DFS (E[i].v,fath);
}
}
int getfather (int x)
{
if (X!=father[x])
Father[x]=getfather (Father[x]);
return father[x];
}
void work (int x)
{
if (first[now[x]]!=x)
{
ans[x]=cnt;
Return
}
int then=now[x];
cnt++;
for (int i=g[then];i;i=e[i].nxt)
{
int v=e[i].v;
if (judge[v]==true)
{
int F=getfather (v), F2=getfather (Now[x]);
if (F!=F2)
{
cnt--;
FATHER[F]=F2;
}
}
}
Judge[now[x]]=true;
ans[x]=cnt;
}
int main ()
{
memset (G,0,sizeof (g));
memset (judge,true,sizeof (judge));
memset (vis,false,sizeof (VIS));
Memset (first,0,sizeof (first));
scanf ("%d%d", &n,&m);
for (int i=1;i<=m;i++)
{
scanf ("%d%d", &x,&y);
Addedge (x, y);
Addedge (Y,X);
}
scanf ("%d", &k);
for (int i=1;i<=k;i++)
{
scanf ("%d", &now[i]);
Father[now[i]]=now[i];
Judge[now[i]]=false;
if (first[now[i]]==0)
First[now[i]]=i;
}
for (int i=0;i<n;i++)
{
if ((Vis[i]==false) && (judge[i]==true))
{
Father[i]=i;
cnt++;
DFS (i,i);
}
}
ans[k+1]=cnt;
for (int i=k;i>=1;i--)
Work (i);
for (int i=1;i<=k+1;i++)
printf ("%d\n", Ans[i]);
return 0;
}
Bzoj 1015 Star Wars