【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
这种输入也是合法的
每个测试用例的第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条道路
测试用例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: 答案错误
****************************************************************/