首页 > 技术文章 > 图论--Dijkstra算法总结

lunatic-talent 2019-08-29 17:16 原文

Key word:

①BFS转换Dijkstra

②其他关系转化为最短路

③反向建边及反向Dijkstra

④稠密图、稀疏图

⑤链式前向星

⑥Vector建图

⑦超级源点&汇点

详解:

1.BFS转换Dijkstra: 对于一些路径的的问题及一些特殊的搜索题目,如果数据量很多但是处理边的复杂程度可以接受,就是说我们可以通过操作将原来要搜索的问题转化为Dijkstra能做的问题,这样可以提高效率,虽然介于BFS与Dijkstra之间有着A*,但是A*的题目我目前就看到了一类,第K短路,常用的还是转换。举个例子:在一个城堡中,有机关陷阱并且告知了其坐标,设城堡为一个二维平面,若这个二维有10000点,BFS最坏的情况是O(V^2)那么可能会超时,那么我们考虑,将每个点的作为节点建图,若有机关则他与上下左右都不连通,其他的每个点建立四联通边,那么时间复杂度为O(4*V),再加上Dijkstra为O(4*V+VlogV)可以将其解出,这个例子可能不太恰当,但是在这里给出解题的思想,BFS与Dijkstra同是单源最短路是可以转化的。

2.其他关系转化为最短路:

我们这里以POJ 1062 昂贵的礼物作为例子

年轻的探险家来到了一个印第安部落里。在那里他和酋长的女儿相爱了,于是便向酋长去求亲。酋长要他用10000个金币作为聘礼才答应把女儿嫁给他。探险家拿不出这么多金币,便请求酋长降低要求。酋长说:"嗯,如果你能够替我弄到大祭司的皮袄,我可以只要8000金币。如果你能够弄来他的水晶球,那么只要5000金币就行了。"探险家就跑到大祭司那里,向他要求皮袄或水晶球,大祭司要他用金币来换,或者替他弄来其他的东西,他可以降低价格。探险家于是又跑到其他地方,其他人也提出了类似的要求,或者直接用金币换,或者找到其他东西就可以降低价格。不过探险家没必要用多样东西去换一样东西,因为不会得到更低的价格。探险家现在很需要你的帮忙,让他用最少的金币娶到自己的心上人。另外他要告诉你的是,在这个部落里,等级观念十分森严。地位差距超过一定限制的两个人之间不会进行任何形式的直接接触,包括交易。他是一个外来人,所以可以不受这些限制。但是如果他和某个地位较低的人进行了交易,地位较高的的人不会再和他交易,他们认为这样等于是间接接触,反过来也一样。因此你需要在考虑所有的情况以后给他提供一个最好的方案。 为了方便起见,我们把所有的物品从1开始进行编号,酋长的允诺也看作一个物品,并且编号总是1。每个物品都有对应的价格P,主人的地位等级L,以及一系列的替代品Ti和该替代品所对应的"优惠"Vi。如果两人地位等级差距超过了M,就不能"间接交易"。你必须根据这些数据来计算出探险家最少需要多少金币才能娶到酋长的女儿。 

对于这个题目,我们考虑每个人是一个节点,他们需要的东西是单向边,那么我们可以建立起一张有向图,可以使用最短路进行计算,类似上次Floyd那个汇率问题这里也可以这么做,所以看到这个题,那么首先要想到最短路去解决才可以。类似的还有很多的题目可以转化为最短路,这个就要自己去理解体会。

3.反向建边及反向Dijkstra与超级源点与超级汇点:https://blog.csdn.net/weixin_43627118/article/details/100134565 

补充:对于反向建边,及反向Dijkstra的应用,比如N个人去编号为X的人家去吃饭,但是N个人所在的城市比较特殊有很多单行线,所以他们来的路可能不是他们回去的路,求他们的来去的走的路程的总和的最小值。这个题走的时候是最短路的距离和来的时候不能去做N遍最短路,那么我们反向建边反向使用Dijkstra,这样最短即是N个点到X的距离最小值。

4.稠密图&稀疏图

稠密图是E边数接近V^2的图,稀疏图接近0(不太恰当,就是边较少),对于稠密图朴素Dijkstra O(V^2)而优化算法为(E+VlogV),边数E接近V^2,所以使用朴素DIjkstra算法。

5.链式前向星:一种关于稀疏图的建图方式:https://blog.csdn.net/weixin_43627118/article/details/99612887

6.vector建图

对于分不太清稠密图和稀疏图的时候可以考虑Vector建图,比直接使用数组模拟稍慢一些,但是有时候用起来还是很不错的比如有一些点的边很多用邻接矩阵存不下,10000个点有一个点跟所有的其他点有边这就很难搞了,但是用邻接表访问没那么方便,所以可以考虑使用,就用过一次,但是不太推荐使用,主推还是邻接表。

 

推荐阅读