题意:
给出一个有N(0<N<=10000)个顶点的无向图(顶点编号0到N-1), 然后依次给出它的M(0<M<=100000)条边,要求依次输出当删除给出的前k(1<=K<=M)条边后,该图的连通分量总数。
输入:第一行是N和M,然后是M行数(X,Y)(0<=X,Y<N)表示X与Y有边。
输出:依次输出所求的连通分量数。
分析:
当删除前K条边时图所剩的连通分量数 就是 N个点孤立时只添加后M-K条边时,所具有的连通分量数。
所以仅需倒序插入每条边,分别保存插入边后新图所具有的连通分量数目在数组内,然后输出数组即可.
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int fa[10005];
int findset(int x)
{
if(fa[x]==-1)
return x;
return fa[x]=findset(fa[x]);
}
int bindd(int u,int v)
{
int fu=findset(u);
int fv=findset(v);
if(fu!=fv)
{
fa[fu]=fv;
return 1;//连通分量少了一个
}
return 0;
}
int main()
{
int n,m,i,ans,x,y;
vector<pair<int,int> >edge;
vector<int>res;
while(~scanf("%d%d",&n,&m))
{
memset(fa,-1,sizeof(fa));
edge.clear();
res.clear();
for(i=0;i<m;i++)
{
scanf("%d%d",&x,&y);
edge.push_back(make_pair(x,y));
}
ans=n;//一开始连通分量
res.push_back(ans);
for(i=m-1;i>=1;i--)
{
ans-=bindd(edge[i].first,edge[i].second);
res.push_back(ans);
}
for(i=res.size()-1;i>=0;i--)
printf("%d\n",res[i]);
}
}