逆序建图,把答案存入一个栈中。详见AC代码
/**************************************************************
Problem: 1015
User: xujiahe
Language: C++
Result: Accepted
Time:1644 ms
Memory:80192 kb
****************************************************************/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <stack>
using namespace std;
#define maxn 1000010
int to[maxn*4],val[maxn*4],next[maxn*4],p[maxn*4];
int father[maxn],mark[maxn],used[maxn],order[maxn];
int m,n,d,cnt;
int tmp=0;
stack<int>ans;
int getfather(int x)
{
if(x==father[x])
{
return x;
}
else
{
father[x]=getfather(father[x]);
return father[x];
}
}
void build(int a,int b)
{
cnt++;
to[cnt]=b;
next[cnt]=p[a];
p[a]=cnt;
}
void init()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
father[i]=i;
}
int a,b;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
build(a+1,b+1);
build(b+1,a+1);
}
scanf("%d",&d);
for(int i=1;i<=d;i++)
{
scanf("%d",&order[i]);
order[i]=order[i]+1;
mark[order[i]]=true;
}
for(int i=1;i<=n;i++)
{
if(mark[i]) continue;
for(int j=p[i];j;j=next[j])
{
if(mark[to[j]]) continue;
int r1=getfather(i);
int r2=getfather(to[j]);
if(r1!=r2) father[r1]=r2;
}
}
for(int i=1;i<=n;i++)
{
if(getfather(i)==i && !mark[i])
tmp++;
}
ans.push(tmp);
}
void solve(int k)
{
int i=order[k];
tmp++;
mark[i]=false;
for(int j=p[i];j;j=next[j])
{
if(mark[to[j]]) continue;
int r1=getfather(i);
int r2=getfather(to[j]);
if(r1!=r2)
{
father[r1]=r2;
tmp--;
}
}
ans.push(tmp);
}
void work()
{
for(int i=d;i>0;i--)
{
solve(i);
}
int len=ans.size();
for(int i=1;i<=len;i++)
{
printf("%d\n",ans.top());
ans.pop();
}
}
int main()
{
init();
work();
return 0;
}