又看了一个小时的dp没搞懂,转战别的
题意:给出n个点,m条边的无向图,以此删除输入的第一条边、第二条边···第m条边,输出删除边后相应的连通分量的个数。
分析:
当删除前K条边时图所剩的连通分量数 就是 N个点孤立时只添加后M-K条边时,所具有的连通分量数
所以仅需倒序插入每条边,分别保存插入边后新图所具有的连通分量数目在数组内,然后输出数组即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int fa[10005];
//返回x节点的艮,同时使得x节点直接挂在根结点的下面
int findset(int x)
{
if(fa[x]==-1)
return x;
return fa[x]=findset(fa[x]);
}
//合并u v所属的连通分量
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));//初始化fa
edge.clear();//不加清空会wa
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]);
}
}