【C++】ZZ1279-畅通工程 解题精讲

【Horn Coding Studio】CPP编程专栏

题目

题目描述

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

输入

测试输入包含若干个测试用例。
每个测试用例的第1行给出两个正整数,分别表示城镇的数目N (N < 1000)和道路的数目M;
随后的M行对应M条道路,每行给出一对正整数,表示该条道路直接连通的两个城镇的编号,城镇从1到N编号。
当N为0时,表示测试用例输入结束,且该用例不被处理。
注意:两个城市之间可以有多条道路相通,也就是说
3 3
1 2
1 2
2 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
0
2
998

提示

输入样例解析,该样例一共包含4个测试用例:
测试用例1:
4 2
1 3
4 3
城镇数量为4,有(1, 3)、(4, 3)两条道路

测试用例2:
3 3
1 2
1 3
2 3
城镇数量为3,有(1, 2)、(1, 3)、(2, 3)三条道路

测试用例3:
5 2
1 2
3 5
城镇数量为5,有(1, 2)、(3, 5)两条道路

测试用例4:
999 0
城镇数量为999,有0条道路

最后一个0,表示输入结束

来源

知识点普及

并查集:被很多OIer认为是最简洁而优雅的数据结构之一,主要用于解决一些元素分组的问题。它管理一系列不相交的集合,并支持两种操作:

  • 合并(Union):把两个不相交的集合合并为一个集合。
  • 查询(Find):查询两个元素是否在同一个集合中。

一点即通

这是一个比较简单的题目,运用了查并集的算法思想,先分别将各个的城镇当做一个集合,当一条道路通往2个城镇时,将这2个城镇并到一个集合中,变成新的集合,然后在最后分集合,在算要建多少条路。

举个例子:

假设有N = 5个城市,编号分别为1 2 3 4 5
然后输入三对数据表示联通的道路
1 2
3 4
2 5
输入1 2之后,城市联通情况为1—2 3 4 5
输入3 4之后,城市联通情况为1—2 3—4 5
输入2 5之后,城市联通情况如图:1—2 3—4 2—5

不难发现,输入所有的数据之后,图中有两个集合

1—2—5
3—4
且只需要连接3—5一条道路,就可以使所有城市互通。

代码

ZZOJ     14%WA     *数据有问题

LuoguOJ     *没有这道题目

#include <bits/stdc++.h>
#define ull unsigned long long int
using namespace std;
ull f[10001];
ull n;
ull a,b,e,d,sum=0;
ull take(ull sums){
    if(f[sums]==sums){
        return sums;
    }else{
        return f[sums]=take(f[sums]);
    }
}
void turn(ull s1,ull s2){
    ull t1=take(s1);
    ull t2=take(s2);
    if(t1!=t2){
        f[t2]=t1;
    }
}
int main() {
    while(true) {
        sum=0;
        cin>>a;
        if(a==0) {
            return 0;
        }
        cin>>b;
        for(ull i=1; i<=a; i++) {
            f[i]=i;
        }
        for(ull i=1; i<=b; i++) {
            cin>>e>>d;
            turn(e,d);
        }for(ull i=1;i<=a;i++){
            if(f[i]==i){
                sum++;
            }
        }cout<<sum-1<<endl;
    }
    return 0;
}
/**************************************************************

    User: FZK

    Language: C++

    Result: 答案错误

****************************************************************/
 

 

posted @ 2022-06-11 21:56  冯子坤  阅读(117)  评论(0编辑  收藏  举报