题意:
给出一个无向图..然后不断的删边..问每次删边后..整个图是由几个联通块组成的....
题解:
以前做过一个题..是CF上面的...是不断的删边..并询问某两点的最短路..当时的方法是倒过来..把删边过程看作加边过程..用floyd维护..
本题也类似..倒过来做把删边看作加边..由于是问联通块..用并查集维护...开始先将没出现在删边中的边连上..再从后往前加边...
Program:
#include<iostream>
#include<stdio.h>
#include<cmath>
#include<string.h>
#include<stack>
#include<queue>
#include<algorithm>
#define oo 1000000007
#define ll long long
#define MAXN 100005
using namespace std;
struct node
{
int x,y;
}line[MAXN];
int father[MAXN],query[MAXN],ans[MAXN];
bool inquery[MAXN];
int getfather(int x)
{
if (father[x]==x) return x;
return father[x]=getfather(father[x]);
}
int main()
{
int n,m,t;
while (~scanf("%d%d",&n,&m))
{
int i,p;
for (i=1;i<=m;i++) scanf("%d%d",&line[i].x,&line[i].y);
scanf("%d",&t);
memset(inquery,false,sizeof(inquery));
for (i=1;i<=t;i++) scanf("%d",&query[i]),inquery[query[i]]=true;
for (i=1;i<=n;i++) father[i]=i;
p=n;
for (i=1;i<=m;i++)
if (!inquery[i])
{
int fx,fy;
fx=getfather(line[i].x);
fy=getfather(line[i].y);
if (fx!=fy)
{
p--;
father[fx]=fy;
}
}
for (i=t;i>=1;i--)
{
int fx,fy;
fx=getfather(line[query[i]].x);
fy=getfather(line[query[i]].y);
ans[i]=p;
if (fx!=fy)
{
p--;
father[fx]=fy;
}
}
for (i=1;i<=t;i++) printf("%d ",ans[i]);
printf("\n");
}
return 0;
}