畅通工程---并查集
畅通工程
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 77565 Accepted Submission(s): 41180
注意:两个城市之间可以有多条道路相通,也就是说
3 3
1 2
1 2
2 1
这种输入也是合法的
当N为0时,输入结束,该用例不被处理。
#include<iostream> using namespace std; int p[1000005], r[1000005]; int n,t; void init()//初始化集合,每个元素的老板都是自己 {for (int i = 1; i <= n; i++){p[i] = i;} }int find(int x)//查找元素x的老板是谁 {if (x == p[x])return x;elsereturn p[x] = find(p[x]); }void join(int x, int y)//合并两个集合 {int xRoot = find(x);int yRoot = find(y);if (xRoot == yRoot) //老板相同,不合并return;if (r[xRoot] < r[yRoot]) //r[i]是元素i所在树的高度,矮树的根节点认高树的根节点做老板p[xRoot] = yRoot;else if (r[xRoot] > r[yRoot])p[yRoot] = xRoot;else{p[yRoot] = xRoot;//树高相同,做老板的树高度要加一r[xRoot]++;} }bool sameRoot(int x, int y)//查询两个元素的老板是否相同 {return find(x) == find(y); } int main() {int m, x, y;while (cin >> n && n != 0){t = 0;cin >> m;init();for (int i = 0; i < m; i++)//把已知联通的元素加入集合 {cin >> x >> y;if (sameRoot(x, y))continue;elsejoin(x, y);}for (int i = 1; i <= n; i++)//有多少个p[i]==i,就有多少个子集 {if (p[i] == i)t++;}cout << t-1 << endl;}return 0; }
第二种方法:假设刚开始所有元素各不相连,此时子集个数有cnt=n个,每加入一条边,子集个数减少一个
#include<iostream> using namespace std; int p[1000005], r[1000005]; int n,t,cnt; void init()//初始化集合,每个元素的老板都是自己 {for (int i = 1; i <= n; i++){p[i] = i;} }int find(int x)//查找元素x的老板是谁 {if (x == p[x])return x;elsereturn p[x] = find(p[x]); }void join(int x, int y)//合并两个集合 {int xRoot = find(x);int yRoot = find(y);if (xRoot == yRoot) //老板相同,不合并return;cnt=cnt-1;if (r[xRoot] < r[yRoot]) //r[i]是元素i所在树的高度,矮树的根节点认高树的根节点做老板p[xRoot] = yRoot;else if (r[xRoot] > r[yRoot])p[yRoot] = xRoot;else{p[yRoot] = xRoot;//树高相同,做老板的树高度要加一r[xRoot]++;} }bool sameRoot(int x, int y)//查询两个元素的老板是否相同 {return find(x) == find(y); } int main() {int m, x, y;while (cin >> n && n != 0){cnt=n;//当元素各不相连的时候,有n个集合t = 0;cin >> m;init();for (int i = 0; i < m; i++)//把已知联通的元素加入集合 {cin >> x >> y;if (sameRoot(x, y))continue;elsejoin(x, y);}// for (int i = 1; i <= n; i++)//有多少个p[i]==i,就有多少个子集// {// if (p[i] == i)// t++;// }cout << cnt-1 << endl;}return 0; }
转载于:https://www.cnblogs.com/-citywall123/p/10717232.html
畅通工程---并查集相关推荐
- ACM: 畅通工程-并查集-解题报告
畅通工程 Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Description某省调查城镇交通状况, ...
- 畅通工程(并查集模版题)
题意: 多组输入N,M,当N为0退出人输入,N是道路数目,M是村庄总数,随后N行,每行输入三个数两个村庄的编号,以及连接这两个村庄的费用. 对每一组数据输出畅通工程的最低费用,如果不能畅通就输出&qu ...
- PIPI OJ 1118: 继续畅通工程(并查集+最小生成树)
菜鸟生成记(18) 1118: 继续畅通工程 又双叒叕是最短路径的水题;不同的是,在构造最小生成树前,题目中已经规定一些已经建好了(这些边已经在生成树里面了);从未建好的边中选择最优边加入生成树;直到 ...
- NYOJ 608 畅通工程 并查集
畅通工程 时间限制:2000 ms | 内存限制:65535 KB 难度:3 描述 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府"畅通工程&qu ...
- ACM-NEFUOJ-P210畅通工程并查集
题目:我已经明示到这个程度了你还不用并查集? #include<bits/stdc++.h>using namespace std;const int MAXN=1010;int F[MA ...
- 九度OJ 1024 畅通工程 -- 并查集、贪心算法(最小生成树)
题目地址:http://ac.jobdu.com/problem.php?pid=1024 题目描述: 省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有 ...
- HDU 1232 -畅通工程(并查集)
题目 http://acm.hdu.edu.cn/showproblem.php?pid=1232 代码 #include <iostream> #include <algorith ...
- nyoj 1239-引水工程 //并查集
1239-引水工程 内存限制:64MB 时间限制:2000ms 特判: No 通过数:58 提交数:130 难度:3 题目描述: 南水北调工程是优化水资源配置.促进区域协调发展的基础性工程,是新中国成 ...
- 并查集 HDOJ 1232 畅通工程
题目传送门 1 /* 2 并查集(Union-Find)裸题 3 并查集三个函数:初始化Init,寻找根节点Find,连通Union 4 考察:连通边数问题 5 */ 6 #include <c ...
最新文章
- golang 的AES加解密 (CBC/ECB/CFB 模式)
- 小米面试题:单词搜索
- VC++在两个按钮之间连直线和折线
- SUSE下使用syslog-ng部署日志服务器
- Socket连接心跳包的机制总结
- vue中class绑定函数
- 王道 —— 进程互斥的软件实现方法
- spark学习-32-SparkEnv的构造步骤
- 《区块链开发指南》一一导读
- MATLAB/Simulink系统建模与仿真
- 联合分布(二):联合分布
- 关于yolov5出现报错 KeyError: ‘copy_paste‘之类Key问题解决办法
- jvm精通之柳暗花明
- Linux虚拟机之间如何添加互信
- 莫纳什大学计算机专业研究生在哪个校区,盘点莫纳什大学2019年计算机类硕士课程...
- 友盟 推特分享错误
- 合成共轭莫比乌斯索烃研究取得进展
- 蓝牙BQB认证 - HFP profile配置说明
- python分析比赛_实战项目练习 ---- 【2018世界杯】用python分析夺冠球队
- 打脸质疑者!Mobileye市值冲高,公司CEO说出心声
热门文章
- springCloud 学习记录过程
- Bare HTTP不完全是RESTful
- linux 迁移mysql目录_linux默认mysql迁移目录
- oracle last day比较,PLSQL LAST_DAY用法及代码示例
- 要写related_name的两种情况
- python关于row的规范_Python DB-API 2.0规范
- linux串口 接收 字符串_非常好用的 Win10 串口调试助手
- wkwebview 不加载ajax,WKWebView加载显示问题
- php 数组重复最多,PHP获取数组中重复最多元素的简单示例
- java的mwcellarray_Java 数组