• 洛谷P1536 村村通


    .

    P1536 村村通

      • 304通过
      • 513提交
    • 题目提供者JOHNKRAM
    • 标签云端↑
    • 难度普及/提高-
    • 时空限制1s / 128MB

      讨论  题解  

    最新讨论更多讨论

    • 求解 为什么这样的并查姿势…
    • 为什么是并查集

    题目描述

    某市调查城镇交通状况,得到现有城镇道路统计表。表中列出了每条道路直接连通的城镇。市政府“村村通工程”的目标是使全市任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要相互之间可达即可)。请你计算出最少还需要建设多少条道路?

    输入输出格式

    输入格式:

    每个输入文件包含若干组测试测试数据,每组测试数据的第一行给出两个用空格隔开的正整数,分别是城镇数目N(N<1000)和道路数目M;随后的M行对应M条道路,每行给出一对用空格隔开的正整数,分别是该条道路直接相连的两个城镇的编号。简单起见,城镇从1到N编号。

    注意:两个城市间可以有多条道路相通。例如:

    3 3 1 2 1 2 2 1 这组数据也是合法的。当N为0时,输入结束。

    输出格式:

    对于每组数据,对应一行一个整数。表示最少还需要建设的道路数目。

    输入输出样例

    输入样例#1:
    4 2
    1 3
    4 3
    3 3
    1 2
    1 3
    2 3
    5 2
    1 2
    3 5
    999 0
    0
    
    输出样例#1:
    1
    0
    2
    998
    分析:判连通我们一般用并查集,如果这道题是有向图,那么可以先缩点,然后看有几个强连通分量,但是对于无向图而言要怎么操作呢?这个时候我们可以只需要找出每个点的祖先即可,有多少个不同的祖先,即有多少个不同的强连通分量,答案的个数为强连通分量的个数-1(连通n个点最少需要n-1条边)
    #include <iostream>  
    #include <cstdlib>  
    #include <cstdio>  
    #include <cstring>  
    #include <string>  
    #include <algorithm>
    #include <queue>
    #include <stack>
    
    using namespace std;
    
    int n, m,fa[1010],ans;
    
    int find(int x)
    {
        if (x == fa[x])
            return x;
        return fa[x] = find(fa[x]);
    }
    
    int main()
    {
        while (scanf("%d", &n) && n != 0)
        {
            ans = 0;
            for (int i = 1; i <= n; i++)
                fa[i] = i;
            scanf("%d", &m);
            for (int i = 1; i <= m; i++)
            {
                int x, y;
                scanf("%d%d", &x, &y);
                int fx = find(x), fy = find(y);
                fa[fx] = fy;
            }
            for (int i = 1; i <= n; i++)
                if (fa[i] == i)
                    ans++;
            printf("%d
    ", ans - 1);
        }
    
        return 0;
    }
     
  • 相关阅读:
    CCF-Python的内置函数们
    CCF2019-03-Python题解
    Find a Number (记忆化+BFS)
    LeetCode15:三数之和(双指针)
    LeetCode:不用加号的加法(位运算)
    剑指Offer43:1~n整数中1出现的次数(数位DP)
    LeetCode190:颠倒二进制(位运算分治! 时间复杂度O(1))
    LeetCode5716:好因子的最大数目(数学、快速幂)
    python学习笔记:python的字符串拼接效率分析
    LeetCode1806:还原排列的最少操作步数(置换群 or 模拟)
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7073151.html
Copyright © 2020-2023  润新知