并查集.
先将需要去除的边一次性去掉,再一条一条加进来.
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
#define MAXN 100005*2
#define inf 1000000
int head[MAXN],parent[MAXN],ad;
struct node
{
int to,now,value;
}edges[MAXN];
void add_edge(int u,int v)
{
edges[ad].to=v;edges[ad].now=u;edges[ad++].value=1;
edges[ad].to=u;edges[ad].now=v;edges[ad++].value=1;
}
void UFSet()
{
memset(parent,-1,sizeof(parent));
}
int Find(int x)
{
int s;
for(s=x;parent[s]>=0;s=parent[s]);
while(s!=x)
{
int temp=parent[x];
parent[x]=s;
x=temp;
}
return s;
}
void Union(int R1,int R2)
{
int r1=Find(R1),r2=Find(R2);
int temp=parent[r1]+parent[r2];
if(parent[r1]>parent[r2])
{
parent[r1]=r2;
parent[r2]=temp;
}
else
{
parent[r1]=temp;
parent[r2]=r1;
}
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
int i;
int u,v;
ad=0;
memset(head,-1,sizeof(head));
UFSet();
for(i=0;i<m;i++)
{
scanf("%d%d",&u,&v);
add_edge(u,v);
}
int q,ns[MAXN],ans[MAXN];
scanf("%d",&q);
for(i=0;i<q;i++)
{
scanf("%d",&ns[i]);
ns[i]=ns[i]*2-1;
edges[ns[i]].value=inf;
edges[ns[i]^1].value=inf;
}
for(i=0;i<ad;i++)
{
u=edges[i].now;
v=edges[i].to;
if(Find(u)==Find(v))
continue;
else if(edges[i].value!=inf)
Union(u,v);
}
int tem=0;
for(i=1;i<=n;i++)
{
if(parent[i]<0)
tem++;
}
ans[0]=tem;
int k=1;
for(i=q-1;i>0;i--)
{
u=edges[ns[i]].now;
v=edges[ns[i]].to;
if(Find(u)!=Find(v))
{
tem--;
Union(u,v);
}
ans[k++]=tem;
}
for(i=k-1;i>0;i--)
{
printf("%d ",ans[i]);
}
printf("%d\n",ans[0]);
}
return 0;
}