最小生成树的权值(迪杰斯特拉算法)

题目描述

【问题描述】 已知含有n个顶点的带权连通无向 图,采用邻接矩阵存储,邻接矩阵 以三元组的形式给出,只给出不包 括主对角线元素在内的下三角形部 分的元素,且不包括不相邻的顶点 对。求该连通图的最小生成树的权值

【输入形式】 第一行给出结点个数n和三元组的 个数count,以下每行给出一个三元 组,数之间用空格隔开。

【输出形式】 最小生成树的权值

【样例输入】5 8

2 1 7

3 1 6

3 2 8

4 1 9

4 2 4

4 3 6

5 2 4

5 4 2

【样例输入】18


解题思路

初始化:将起点的距离设置为0,将其他节点的距离设置为无穷大。将所有节点标记为未访问状态。

选择节点:从未访问的节点中选择距离起点最近的节点,将其标记为已访问状态。

更新距离:对于与当前节点相邻的节点,计算从起点到这些节点的距离,并更新它们的距离值。如果新的距离值比原来的距离值更小,则更新距离值。

重复步骤2和3,直到所有节点都被访问过或者目标节点被访问到。

回溯路径:从终点开始回溯,沿着每个节点的最短路径找到起点。


源代码

#include<iostream>
using namespace std;
typedef struct Edge {
	int begin, end, weight;   //定义边的两个邻接点、权重
}edgenode;
//递归寻找祖先结点
int Find(int *fathers, int n) {   
	int f = n;
	while (fathers[f] > 0)
		f = fathers[f];
	return f;
}
//建立邻接表
void CreateEdge(edgenode*& node) {
	node = new edgenode;
	cin >> node->begin >> node->end >> node->weight;   //录入两个临界点的序号及边权重
}
//按边权值由小到大排序
void Sort(edgenode* edgelist[], int e) {   
	for (int i = 0; i < e; i++)
		for (int j = 0; j < e - i - 1; j++)
			if (edgelist[j]->weight > edgelist[j + 1]->weight)
				swap(edgelist[j], edgelist[j + 1]);
}
//迪杰斯特拉算法
void Kruskal(edgenode* edgelist[], int e, int& cnt) {   
	int fathers[1000];
	for (int i = 0; i < e; i++)
		fathers[i] = 0;
	int bgf, edf;  
	for (int i = 0; i < e; i++) {
		bgf = Find(fathers, edgelist[i]->begin);
		edf = Find(fathers, edgelist[i]->end);
		if (bgf != edf) {                 //判断是否为一个连通分量
			fathers[edf] = bgf;
			cnt += edgelist[i]->weight;   //存放权值
		}
	}
}
int main() {
	edgenode* edgelist[1000];
	int n, e;   
	cin >> n >> e;   
	for (int i = 0; i < e; i++)
		CreateEdge(edgelist[i]);   
	Sort(edgelist, e);  
	int cnt = 0;   
	Kruskal(edgelist, e, cnt);
	cout << cnt << endl;
	return 0;
}

总结

        迪杰斯特拉算法(与上一篇博客类似)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想我记得写信

您的鼓励是我创作最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值