码迷,mamicode.com
首页 > 其他好文 > 详细

并查集---wannafly2017-12-15 D

时间:2017-12-16 17:24:29      阅读:193      评论:0      收藏:0      [点我收藏+]

标签:连通   wan   gpo   post   oid   分析   amp   示例   100%   

1、题目

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
给你一个 n 个点,m 条边的无向图,求至少要在这个的基础上加多少条无向边使得任意两个点可达~

输入描述:
第一行两个正整数 n 和 m 。
接下来的m行中,每行两个正整数 i 、 j ,表示点i与点j之间有一条无向道路。
输出描述:
输出一个整数,表示答案
示例1
输入

4 2
1 2
3 4
输出

1
备注:
对于100%的数据,有n,m<=100000。

 

2、分析:给定n个点,则有n-1条边就可以实现任意两点连通,所以用并查集解决,只要两个点之间存在一条无向边,则该店的祖先就发生了变化,这样在最后查询的时候就可以确定最后需要连接几条边(即答案)。res-1是代表防止形成环。

3、Code

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100005;
int fa[maxn];
int n,m;

void init()
{
    for(int i = 1; i <= n; i++)
    {
        fa[i] = i;
    }
}

int find(int x)
{
    return fa[x] != x ? fa[x] = find(fa[x]) : fa[x];
}

void unin(int x, int y)
{
    int fx = find(x);
    int fy = find(y);
    if(fx != fy){
        fa[fx] = fy;
    }
}

int main()
{
    int u,v;

    while(~scanf("%d%d",&n,&m)){
        init();

        for(int i = 0; i < m; i++)
        {
            scanf("%d%d",&u,&v);
            unin(u,v);
        }
        int res = 0;
        for(int i = 1; i <= n; i++)
        {
            if(fa[i] == i)
                res++;
        }
        printf("%d\n",res-1);
    }

    return 0;
}

 

并查集---wannafly2017-12-15 D

标签:连通   wan   gpo   post   oid   分析   amp   示例   100%   

原文地址:http://www.cnblogs.com/hhkobeww/p/8046647.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!