hdu4496 求连通分量个数

题意:题意可以转化为:不断给一个图加有边,问每次加边后图的连通分图有多少个。


解法:裸的并查集,开始时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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值