题意:
给你一个n个点的完全无向图,之后给你m条边,现在问你每次按顺序删掉这m条边之后图中有多少个联通块儿,联通块儿的定义是在这样一个块儿种的每一个点都可以直接或者间接的到达每一个点。
思路:
首先明确一点就是在所有拆边前只有一个联通块,而拆完这m条边之后联通块儿的数量为0,那么现在问题就是我们如何删掉这几条边,我们都知道并查集可以建立关系,但是删除关系还是很麻烦,因为在你每次路径压缩之后他的父亲都会丢失,变成他的根节点,在这里想一下,当删除前K条边时图所剩的连通分量数 就是 N个点孤立时只添加后M-K条边时,所具有的连通分量数。
那我们反向存一下边,之后正向建图每次减去同一集合里的数就好了
上代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n,m;
struct node
{
int s,e;
}pre[100002];
int p[10003],ans[100002];
int getf(int x)
{
return p[x]==x?x:p[x]=getf(p[x]);
}
void init()
{
for(int i=0;i<=n;i++)
{
p[i]=i;
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
int sum=0;
memset(pre,0,sizeof(pre));
for(int i=1;i<=m;i++)
{
scanf("%d%d",&pre[i].s,&pre[i].e);
}
ans[m]=n;
for(int i=m;i>=1;i--)
{
int dx=getf(pre[i].s);
int dy=getf(pre[i].e);
if(dx!=dy)
{
sum++;
p[dx]=dy;
}
ans[i-1]=n-sum;
}
for(int i=1;i<=m;i++)
{
printf("%d\n",ans[i]);
}
}
}