简单的并查集aoj连通图

Description

在无向图G中,如果任两结点可达,则称图G是连通的; 如果G的子图G’是连通的,没有包含G’的更大子图G’’是联通的,则称G’是G的连通分图。一个无向图,要么是一个连通

图,要么是由若干个连通分图组成。形象地说,一个无向图的连通分图就是图的一个独立的部分。

由于无向图可能是不连通的,你要做的就是添加最少的边,使无向图成为一个连通图。


Input

顶点数N,N个顶点的编号为1,2,3,……,N(N<= 1000)

边数M (M <= 100000)

接下来有M行,每行两个整数s,t,表示从s到t有边。



Output

输出一行,一个整数cnt,表示要添加最少的边的个数


Sample Input

Original Transformed


5 5

3 2

1 2

1 3

3 4

4 4

Sample Output

Original Transformed

1

分析:简单的并查集。通过合并,将所有可以连通的点连通,再计算有多少个互不连通的图,即可知道还需多少边。

#include<cstdio>
using namespace std;

const int maxn = 1010;

int p[maxn];//存放父亲节点
int n, m;

int Find(int x){
    return p[x] == x ? x : p[x] = Find(p[x]);//寻找根节点
}

void Union(int x, int y){
    int x_root = Find(x);
    int y_root = Find(y);
    if(x_root != y_root){//如果不是连通的
        p[x_root] = y_root;
        n--;//连通它,并且剩下未连通的点减少一个(所需边也减少一个)
    }
}

int main(){
    int a, b;
    scanf("%d%d", &n, &m);
    for(int i = 0; i < n; i++) p[i] = i;//默认每个点的父亲节点就是它本身
    n--;//因为n个点只需n-1条边连接
    for(int i = 0; i < m; i++){
        scanf("%d%d", &a, &b);
        Union(a, b);//合并
    }
    printf("%d\n", n);//输出此时剩下未连通的点的个数(已减一),即至少所需边的数目
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值