图最长路径:深大数据结构期末考上机题3

本文介绍了如何使用修改后的迪杰斯特拉算法解决深大数据结构期末考试中的图最长路径问题。关键在于更新节点时重置访问标志并多更新一次。详细解释了思路、访问重置和多更新一次的原理,并提供了完整的代码实现。
摘要由CSDN通过智能技术生成

图最长路径:深大数据结构期末考上机题3

题目是这样的: 有一无向图,用邻接表存储,求从5顶点出发到各个顶点的最长路径长度,输出 最长路径长度最长路径

偷偷把草稿纸带出来的屑 在这里插入图片描述
输入:
顶点数
边数

样例输入:
8
13
0 2 0.26
1 3 0.29
3 6 0.52
3 7 0.39
4 0 0.38
4 7 0.37
5 1 0.32
5 4 0.35
5 7 0.28
6 0 0.58
6 2 0.4
6 4 0.93
7 2 0.34
样例输出:
5->0 length is 2.44 path is: 5 1 3 6 4 0
5->1 length is 0.32 path is: 5 1
5->2 length is 2.77 path is: 5 1 3 6 4 7 2
5->3 length is 0.61 path is: 5 1 3
5->4 length is 2.06 path is: 5 1 3 6 4
5->6 length is 1.13 path is: 5 1 3 6
5->7 length is 2.43 path is: 5 1 3 6 4 7
OJ当天就关了我也不知道上面的自制样例是不是真的正确

当时卡了好一会,后来改出来了,我是用迪杰斯特拉做的,这里迪杰斯特拉要改几条语句,否则路径不对,然后后面问了下大佬,说是关键路径做的

迪杰斯特拉改的关键

关键就是迪杰斯特拉更新节点 i 的时候要重置 i 节点的路径的访问标志数组,也就是 visited[i] = 0 然后需要多更新一次,因为这一次更新的路径(起点到i)必然作为下一次更新时选择的候选路径,图解原因如下:

大致思路

  • 将已知的最长的,未被选择过的路径 p_max 的终点 max_index 这个节点,作为更新的点
  • 看是否有路径从 max_index 顶点出发,到 j 顶点的路径长度 :length(max_index -> j) + length(起点 -> max_index) 大于已知的到达 j 顶点的路径长度:length(起点 -> j)


length(max_index -> j) + length(起点 -> max_index) > length(起点 -> j) ?

访问重置 的解释

  • 如果更新成功,新路径长度一定大于我们选择的路径的长度,因为多加了一条边(没有负权边)
  • 现在选择的路径已经是已知路径中最长的了,新路径长于现在选择的路径,那么新路径一定是下一次选择最长已知路径中的备选方案,所以visited[]标志要置零

(或者这么理解:假设之前我们有一条A到C点的路径:
[A B C] 叫做 p1,我们认为它是最长的,我们用 p1 更新了A到F,G点的路径,但是现在发现了更长的A到C的路径:
[A D C] 叫做 p2,那么意味着从A到F,G点的路径有了更好的解,所以下一次应该基于 [A D C] 这条路径去更新F,G,但是因为在这之前已经基于 [A D C] 更新过到F,G的路径,visited[C] = 1,所以为了能够再次更新,需要重置标志)
在这里插入图片描述

多更新一次 的解释

  • visited 标志置零说明总的更新次数要比预计的多选一次,故最外圈循环多一次,即 k = k - 1

更新最长路径的代码:

class edge
{
   
public:
	edge();
	int v2;			// 边指向的顶点 
	double weight;	// 边权值 
};

#define maxlen 1009
deque<edge> adj[maxlen];	// 邻接表,edge 是边的类,包含顶点,权值成员
int visited[maxlen];	// visited[i]:起点到 i 节点的路径是否已经被选择过
double path[maxlen];	// path[i]:起点到 i 节点的最长路径长度 
node PATH[maxlen];	// PATH[i]:链表保存起点到 i节点的最长路径 

int n;	// 顶点 
int e;	// 边 
int i, j, k;

// 迪杰斯特拉 改 
for(k=0; k<n; k++)
{
   
	// 选择未被选择过的最长的一条路径 
	double max = -1145141919;
	int max_index = 0;
	for(i=0; i<n; i++)
	{
   
		if(path[i]>max && visited[i]==0
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值