【还是畅通工程 HDU - 1233】【Kruskal模板题】
Kruskal算法讲解
该部分内容全部摘录自刘汝佳的《算法竞赛入门经典》
Kruskal算法的第一步是给所有边按照从小到大的顺序排列。 这一步可以直接使用库函数
qsort或者sort。 接下来从小到大依次考查每条边(u,v)。
情况1: u和v在同一个连通分量中, 那么加入(u, v)后会形成环, 因此不能选择。
情况2: 如果u和v在不同的连通分量, 那么加入(u, v)一定是最优的。 为什么呢? 下面用
反证法——如果不加这条边能得到一个最优解T, 则T+(u, v)一定有且只有一个环, 而且环中
至少有一条边(u' , v')的权值大于或等于(u,v)的权值。 删除该边后, 得到的新树T'=T+(u, v)-(u',
v')不会比T更差。 因此, 加入(u, v)不会比不加入差。
下面是伪代码:
把所有边排序, 记第i小的边为e[i]( 1<=i<m)
初始化MST为空
初始化连通分量, 让每个点自成一个独立的连通分量
for(int i = 0; i < m; i++)
if(e[i].u和e[i].v不在同一个连通分量) {
把边e[i]加入MST
合并e[i].u和e[i].v所在的连通分量
}
在上面的伪代码中, 最关键的地方在于“连通分量的查询与合并”: 需要知道任意两个点
是否在同一个连通分量中, 还需要合并两个连通分量。这就用到了并查集。可以把每个连通分量看成一个集合, 该集合包含了连通分量中的所有点。 这些点两两连通, 而具体的连通方式无关紧要, 就好比集合中的元素没有先后顺序之分, 只有“属于”和“不属于”的区别。 在图中, 每个点恰好属于一个连通分量, 对应到集合表示中, 每个元素恰好属于一个集合。 换句话说, 图的所有连通分量可以用若干个不相交集合来表示。
并查集的精妙之处在于用树来表示集合。 例如, 若包含点1, 2, 3, 4, 5, 6的图有3个
连通分量{1,3}、 {2,5,6}、 {4}, 则需要用3棵树来表示。 这3棵树的具体形态无关紧要, 只要
有一棵树包含1、 3两个点, 一棵树包含2、 5、 6这3个点, 还有一棵树只包含4这一个点即
可。 规定每棵树的根结点是这棵树所对应的集合的代表元( representative) 。
如果把x的父结点保存在p[x]中( 如果x没有父结点, 则p[x]等于x) , 则不难写出“查找结
点x所在树的根结点”的递归程序: int find(int x) { p[x] == x ? x : find(p[x]); }, 通俗地讲就是:
如果p[x]等于x, 说明x本身就是树根, 因此返回x; 否则返回x的父结点p[x]所在树的树根。
问题来了: 在特殊情况下, 这棵树可能是一条长长的链。 设链的最后一个结点为x, 则
每次执行find(x)都会遍历整条链, 效率十分低下。 看上去是个很棘手的问题, 其实改进方法
很简单。 既然每棵树表示的只是一个集合, 因此树的形态是无关紧要的, 并不需要在“查
找”操作之后保持树的形态不变, 只要顺便把遍历过的结点都改成树根的子结点, 下次查找
就会快很多了。

关于并查集的更深一步了解可以看一下这个博文。
题目讲解及AC代码
题目讲解
这个题目不难看出是个寻找最短路的问题,用Kruskal算法+并查集比较合适
AC代码
/*Kruskal算法*/
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn = 100 + 10;
int N, father[maxn];
struct Road
{
int _st, _en, _dist;
};
Road r[maxn*maxn];
bool cmp(Road a, Road b)
{
return a._dist < b._dist;
}
int Find(int root)
{
if(root != father[root])
father[root] = Find(father[root]);
return father[root];
}
int main()
{
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
while(cin >> N && N)
{
for(int i = 1; i <= N; i++)
father[i] = i;
for(int i = 0; i < N * (N - 1) / 2; i++)
cin >> r[i]._st >> r[i]._en >> r[i]._dist;
sort(r, r + N*(N-1)/2, cmp);
int ans = 0;
for(int i = 0; i < N * (N - 1) / 2; i++)
{
int st_ = r[i]._st, en_ = r[i]._en;
int x = Find(st_), y = Find(en_);
if(x != y )
{
ans += r[i]._dist;
father[x] = y;
}
}
cout << ans << endl;
}
}
【还是畅通工程 HDU - 1233】【Kruskal模板题】的更多相关文章
- HDU-1232/NYOJ-608畅通工程,并查集模板题,,水过~~~
畅通工程 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) http://acm. ...
- L - 还是畅通工程 - hdu 1233
Description 某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离.省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达 ...
- poj 1251 poj 1258 hdu 1863 poj 1287 poj 2421 hdu 1233 最小生成树模板题
poj 1251 && hdu 1301 Sample Input 9 //n 结点数A 2 B 12 I 25B 3 C 10 H 40 I 8C 2 D 18 G 55D 1 E ...
- HDU1232 畅通工程 (并查集模板题)
畅通工程 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- HDU 1233 最小生成树模板题,练练模板
还是畅通工程 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...
- 畅通工程 HDU - 1863 最小生成树模板
两个模板: kruskal #include<stdio.h> #include<queue> #include<algorithm> #include<io ...
- 还是畅通工程 HDU - 1233
题目链接:https://vjudge.net/problem/HDU-1233 思路: 最小生成树板子. #include <iostream> #include <stdio.h ...
- HDU 1863 畅通工程(Prim,Kruskal,邻接表模板)
畅通工程 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- hdu 1233 还是畅通工程 (prim, kruskal)
还是畅通工程Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submi ...
随机推荐
- 福州大学软件工程1916|W班 第10、11次作业成绩排名
作业链接 项目Alpha冲刺(团队) 事后诸葛亮(团队) 评分细则 博客评分标准 本次作业包括现场Alpha答辩评分(映射总分为100分)+博客分(总分130分)+贡献度得分,其中博客分由以下部分组成 ...
- kube-prometheus部署
一.从git拉取相应yaml文件 git clone https://github.com/coreos/kube-prometheus.git 二.修改grafana及prometheus的serv ...
- Struts2利用iText导出word文档(包含表格)以提供下载
J2EE ExcelStrutsXML 在公司实习期间,带我的老师让我实现一功能——在显示课表的页面上上点击“导出文件“时能以word文档形式下载课表.将课表导出到excel里的功能他们已经实现了, ...
- Selenium基础教程(二)环境搭建
一.环境搭建 (1)初学者最佳环境: Python 2.7 + Selenium 2+ Firefox 46 (2)喜欢尝新的环境: Python 3.6 + Selenium 3+ Firefox ...
- IP地址结构(转载)
分类寻址(网络号+主机号) 在最初定义Internet地址结构时,每个单播IP地址都有一个网络部分,用于识别接口使用的IP地址在哪个网络中可被发现:以及一个主机地址,用于识别由网络部分给出的网络中的特 ...
- PyCharm+SVN配置使用教程
一.说明 去年写“PyCharm+Miniconda3安装配置教程”的时候就想把配置SVN的内容加上,但刚开始使用不是很清楚操作就先算了,然后到后边知道怎么操作之后觉得比较简单不写也可以. 一是昨天使 ...
- dockerfile 命令
FROM 功能为指定基础镜像,并且必须是第一条指令. 如果不以任何镜像为基础,那么写法为:FROM scratch. 同时意味着接下来所写的指令将作为镜像的第一层开始 语法: FROM <ima ...
- 043 用户注册功能03--Redis安装及完成短信发送功能
1.Redis安装 (1)下载地址:https://github.com/MicrosoftArchive/redis/releases/tag/win-3.2.100 ( redis官网: ht ...
- [WeChat-Bot-Go] 记录帖
本来是想写一个微信机器人出来,用go语言. Github 目标是想做一个自动发送消息和抢红包的bot. 一开始跟着 这篇 文章写.写着写着发现文章久远,而且用的是第一版网页微信api,所以就自己去 ...
- SpringApplication常见用法说明
启动方式 方式1:在main方法中执行SpringApplication.run()这种方式来启动我们的工程 // 方式一 @SpringBootApplication public class Ap ...