数据结构:可以用求最短路径的方法思想求最长路径么?给出详细解答。。

数据结构:可以用求最短路径的方法思想求最长路径么?为什么呢?

这里求解最短路径的通用方法有Dijkstra算法和Floyd-Warshall算法,Dijkstra算法不允许边的权值为负,也不允许有回路,而Floyd-Warshall算法可以允许边的权值为负,但不允许负值边构成回路,即可以求解有回路的图

它们都有局限,这两种算法的思想可以用来求最长路径么??

为什么 不可以?

(感谢给我答案的好心人:来自于知乎:http://www.zhihu.com/question/27201255和CSDN)

以下整理出详细解答:

1)      不可以,核心在于最短路问题是有最优子结构的,就是『最短路的子路径还是最短路』,而最长路径不存在这个子结构。这里的最长路径是指两个节点之间最长简单路径(路径不循环)。考虑下算法导论上面的例子:有两条最长的路径与Q到T:Q–
> R –> T和Q– > S-> T。不像最短路径,这些路径最长不具有最优子属性。例如,最长路径q->
r-> t不是由q->r和r->t的组合,因为最长的路径从q至r为q->
s-> t->r

2)        不可以。最短路径问题是P的,但最长路径问题是NP-hard的:

证明最长路径问题是NP-Hard的

Proof:假如最长路径问题有多项式时间算法A,我们证明Hamilton回路问题也有多项式时间算法,从而建立Turing归约。

对任意一个图G=<V,E>,用如下算法检查其是否有Hamilton回路:

给所有边赋权值1,取定V中一个顶点v

对所有v ‘∈V,循环:

如果<v,v ‘ >∈E且
v 到v ‘的最长路径长度=|V|-1(用A计算)

那么G有Hamilton回路;

结束循环

如果所有v ‘
均不满足上述条件,则G没有Hamilton回路;

很明显,如果算法A是多项式时间的,那么上述Hamilton回路问题的算法也是多项式时间的,从而最长路径问题是NP-Hard的

3)        肯定不能用dijkstra算法,这是因为,Dijkstra算法的大致思想是每次选择距离源点最近的结点加入,然后更新其它结点到源点的距离,直到所有点都被加入为止。当每次选择最短的路改为每次选择最长路的时候,出现了一个问题,那就是不能保证现在加入的结点以后是否会被更新而使得到源点的距离变得更长,而这个点一旦被选中将不再会被更新。例如这次加入结点u,最长路为10,下次有可能加入一个结点v,使得u通过v到源点的距离大于10,但由于u在之前已经被加入到集合中,无法再更新,导致结果是不正确的。如果取反用dijkstra求最短路径呢,记住,dijkstra不能计算有负边的情况。。。

4)        不能用Floyd-Warshall算法求每对节点之间的最长路经:因为如果图中含有回路(且回路中不含负值),Floyd算法并不能判断出其中含有回路,且会求出一个错误的解。

请勿拍砖,欢迎交流。。

时间: 2024-12-23 11:36:45

数据结构:可以用求最短路径的方法思想求最长路径么?给出详细解答。。的相关文章

数据结构:单源最短路径--Dijkstra算法

Dijkstra算法 单源最短路径 给定一带权图,图中每条边的权值是非负的,代表着两顶点之间的距离.指定图中的一顶点为源点,找出源点到其它顶点的最短路径和其长度的问题,即是单源最短路径问题. Dijkstra算法 求解单源最短路径问题的常用方法是Dijkstra(迪杰斯特拉)算法.该算法使用的是贪心策略:每次都找出剩余顶点中与源点距离最近的一个顶点. 算法思想 带权图G=<V,E>,令S为已确定了最短路径顶点的集合,则可用V-S表示剩余未确定最短路径顶点的集合.假设V0是源点,则初始 S={V

43. 蛤蟆的数据结构笔记之四十三最短路径之迪杰斯特拉(Dijkstra )算法

43. 蛤蟆的数据结构笔记之四十三最短路径之迪杰斯特拉(Dijkstra )算法 本篇名言:"辛勤的蜜蜂永没有时间悲哀.--布莱克" 这次来看下Dijkstra )算法.还是老方法,先原理,后实现.代码来自网络. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/47046031 1.  最短路径 最短路径问题是图论研究中的一个经典算法问题, 旨在寻找图(由结点和路径组成的)中两结点之间的最短路径. 管道铺设.线路安排

数据结构与算法——无权最短路径算法的C++实现

对于一个有权图,任意路径中各个边的权重的和,就是加权路径长. 对于一个无权图,任意路径中边的数目,就是无权路径长. 对于上面的无权图G,我们使用某个顶点s作为输入参数,我们想要找出从s到所有其它顶点的最短路径.我们只对路径上边的数目感兴趣,不考虑路径上边的权重(对于无权图可以将权重看为是1). 算法1详细步骤: 1.选择顶点s为v3.马上可以知道s到v3的最短路径长为0的路径(v3->v3) 2.寻找从s出发路径长为1的顶点,这些点都是s的邻接点. 3.寻找从s出发路径长为2的顶点.找到v1和v

分治策略结合递归思想求最大子序列和

我的主力博客:半亩方塘 对于 <数据结构与算法分析--C语言描述> 一书第 20 页所描述的算法 3,相信会有很多人表示不怎么理解,下面我由具体问题的求解过程出发,谈谈我自己的理解: 首先,什么是分治法呢?所谓 分治法,就是 将一个问题的求解过程分解为两个大小相等的子问题进行求解,如果分解后的子问题本身也可以分解的话,则将这个分解的过程进行下去,直至最后得到的子问题不能再分解为止,最后将子问题的解逐步合并并可能做一些少量的附加工作,得到最后整个问题的解.在求解原来整个问题的算法思想,与求解每一

list1与list2求交集的方法总结!

一.有序集合求交集的方法有 a)二重for循环法,时间复杂度O(n*n) b)拉链法,时间复杂度O(n) c)水平分桶,多线程并行 d)bitmap,大大提高运算并行度,时间复杂度O(n) e)跳表,时间复杂度为O(log(n)) 以下是方法的具体介绍: 方案一:for * for,土办法,时间复杂度O(n*n) 每个搜索词命中的网页是很多的,O(n*n)的复杂度是明显不能接受的.倒排索引是在创建之初可以进行排序预处理,问题转化成两个有序的list求交集,就方便多了. 方案二:有序list求交集

Dijkstra算法求最短路径 C++实现

Dijstra算法代码借鉴: #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #define Inf 0x3f3f3f3f using namespace std; int map[1005][1005];//存储输入数组值 int vis[1005],dis[1005];//vis标记数组,dis最短路径 int n,m;//n个点,m条边 void Ini

Java大集合求交集的方法比较

两个List集合求交集想必学过Java的都知道用系统自带的retainAll()方法,但是在数据量比较大时,这个方法效率并不高,利用空余时间研究了几种数据量较大时求两个集合交集的办法.本文主要研究了JDK自带方法求交集.Guava集合求交集.Java8的parallelStream并行流求交集.双指针方法求交集以及bitmap求交集的方法和效率. JDK自带方法 最常用的求交集方法,在小数据量的时候没什么问题,一旦两个集合的数据量达到几十万级别时,效率就严重偏低,底层实际上也是两个for循环,只

数据结构之单源最短路径(迪杰斯特拉算法)-(九)

最开始接触最短路径是在数据结构中图的那个章节中.运用到实际中就是我在大三参加的一次美赛中,解决中国的水资源问题.所谓单源最短路径,就是一个起点到图中其他节点的最短路径,这是一个贪心算法. 迪杰斯特拉算法原理(百科): 按路径长度递增次序产生算法: 把顶点集合V分成两组: (1)S:已求出的顶点的集合(初始时只含有源点V0) (2)V-S=T:尚未确定的顶点集合 将T中顶点按递增的次序加入到S中,保证: (1)从源点V0到S中其他各顶点的长度都不大于从V0到T中任何顶点的最短路径长度 (2)每个顶

线段树求逆序数方法 HDU1394&amp;&amp;POJ2299

为什么线段树可以求逆序数? 给一个简单的序列 9 5 3 他的逆序数是3 首先要求一个逆序数有两种方式:可以从头开始往后找比当前元素小的值,也可以从后往前找比当前元素大的值,有几个逆序数就是几. 线段树就是应用从后往前找较大值得个数.(一边更新一边查) 当前个数是 n = 10 元素   9  5   3 9先加入线段树,T[9]+=1:查从T[9]到T[10]比9大的值,没有sum = 0: 5 加入线段树,T[5] += 1,查从T[5]到T[10]比5大的值,有一个9,sum +=1: 3