HDU 1232 并查集 (入门)
2017-01-17 23:38
519 查看
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1232
畅通工程
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 49690 Accepted Submission(s): 26509
[align=left]Problem Description[/align]
某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇。省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可)。问最少还需要建设多少条道路?
[align=left]Input[/align]
测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是城镇数目N ( < 1000 )和道路数目M;随后的M行对应M条道路,每行给出一对正整数,分别是该条道路直接连通的两个城镇的编号。为简单起见,城镇从1到N编号。
注意:两个城市之间可以有多条道路相通,也就是说
3 3
1 2
1 2
2 1
这种输入也是合法的
当N为0时,输入结束,该用例不被处理。
[align=left]Output[/align]
对每个测试用例,在1行里输出最少还需要建设的道路数目。
[align=left]Sample Input[/align]
4 2 1 3 4 3 3 3 1 2 1 3 2 3 5 2 1 2 3 5 999 0 0
[align=left]Sample Output[/align]
1 0 2 998 博主: 在做这一题之前,我几乎对并查集是一点概念没有,然乎在网上看到了--->http://www.cnblogs.com/cyjb/ 这位大佬的博客,感觉秒懂啊,确实佩服这位大佬的讲解能力,推荐看一看,我就单说HDU-1232这一题了。 我的思路:要使全省任何两个城镇间都可以实现交通,而且直接间接都可以,那就很简单了,有n个城镇只需n-1条路就可以了,而城镇的数量就是联通块的数量,也就是说这一题等价于已知一个无向图,求其中连通块的数量。 每一连通块都应该有一个“代表”,这个代表是该块中的某一个点,当然,“代表”的“代表”是其自己,以“代表”来判别某两个点是否在一个连通块里面,那么很自然的,我们的代码里面就应该有这两个函数:find(x),即寻找点x的“代表”,mix(a,b)将点a所在的块与点b所在块合并,合并之后的代表可以是之前a的代表也可以是b的代表,当然,这并不重要,我们自己默认就可以了。 代码如下:[code]/* *Li Wenjun *Email:1542113545@qq.com *function: 并查集 */ #include<stdio.h> #include<string.h> #include<math.h> #include <iostream> #include <algorithm> #include <cstring> #include <cmath> #include <queue> #include <vector> #include <stack> #include <list> #include <cstdlib> #include <set> using namespace std; #define MAXN 1050 #define M(a,b) memset(a,b,sizeof(a)) int pre[MAXN]; bool t[MAXN]; int Find( int rt ) { int r = rt; while(r != pre[r]) r = pre[r]; int temp = rt; while( pre[temp] != r) { int j = pre[temp]; pre[temp] = r; temp = j; } return r; } int mix(int x, int y) { int fx= Find( x ),fy= Find( y ); if(fx != fy) { pre[fx] = pre[fy]; } return 0; } int main() { cin.tie(0); cin.sync_with_stdio(false); int N,M,a,b,ans; while(cin>>N>>M) { for(int i=1 ; i<=N;i++) pre[i] = i; for(int i=1; i<=M; i++) { cin>>a>>b; mix(a , b); } M(t,0); for(int i=1; i<=N ; i++) { t[Find(i)] = 1; } int ans = 0; for(int i=1; i<=N; i++) ans+=(t[i]? 1 : 0); cout << ans-1 << endl; } return 0; }
[/code]
相关文章推荐
- HDU1232 畅通工程 并查集入门
- HDU 1232 畅通工程 入门并查集 附大牛讲解 4000
- hdu 1232 并查集入门
- HDU 1232 解题报告 并查集入门
- hdu 1232 畅通工程【并查集入门】
- hdu-1232-畅通工程(并查集入门题)
- hdu 1232 畅通工程(入门之并查集)
- 并查集 入门-HDU 1232
- hdu 1232 畅通工程【并查集入门】
- 【并查集入门】HDU1232——畅通工程
- hdu 1232畅通工程 并查集(入门题)
- hdu 1232 并查集
- HDU 1232 畅通工程 (并查集)
- HDU1232(简单并查集)
- hdu 1232 借助这题学习了下并查集的路径压缩
- hdu 1232 并查集 或者 深搜
- hdu 1856 More is better (并查集入门)
- HDU 1232 & 1213并查集应用 练习
- 杭电1232//并查集入门
- HDU-1232(并查集)