题意:题意可以转化为:不断给一个图加有边,问每次加边后图的连通分图有多少个。
解法:裸的并查集,开始时n个点各自属于一个连通分量。每次加边都有可能将两个联通分量连起来,也有可能是在一个联通分量加了一条边。主要就是判断加边的两个点的根父母是否是同一个点,若是则两点属于同一个连通分量,否则就是两个联通分量,这时连通分量数就会减一。
代码:
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <vector>
using namespace std;
int parent[100100];
int getparent(int k)
{
if(parent[k]==k)
return k;
return parent[k]=getparent(parent[k]);
}
int N,M;
struct point
{
int u,v;
} points[100010];
vector<int> vec;
int rem[100010];
int main()
{
while(scanf("%d%d",&N,&M)==2)
{
vec.clear();
for(int i=0;i<=N;i++)
parent[i]=i;
for(int i=M-1;i>=0;i--)
scanf("%d%d",&points[i].u,&points[i].v);
int ans=N;
int p=0;
for(int i=0;i<M;i++)
{
rem[p++]=ans;
int t1=getparent(points[i].u);
int t2=getparent(points[i].v);
if(t1!=t2)
{
parent[t1]=getparent(t2);ans--;
}
}
for(int i=M-1;i>=0;i--)
cout<<rem[i]<<'\n';
}
return 0;
}