入门——最短路(floyd, dijkstra)

冷暖自知 提交于 2020-02-19 09:16:22

今天讲图论基础和两种最短路算法。

老实说,我不觉的我能把最短路讲好,因为我主功不是图论,好久没有用了。本来只想找几篇博客放这里,但是发现现在的博客鱼龙混杂,感觉自己更应该讲好了。。。

首先要对图论有个大概的了解,尽管是刚入门,但是为了以后的学习还是要知道图论的基础名词的,我不是科班出身只能引用大佬的博客:https://blog.csdn.net/saltriver/article/details/54428685?utm_source=distribute.pc_relevant.none-task

了解了正统的图论以后,那么现在你只需要记住今天算法的应用范围就行:带有权的连通图,换句话说就是有很多点,这些点都有路能串起来并且这些路或者点是有数据的。我们今天讲的最短路算法就主要计算任意两点间的最短距离。最短路的算法有很多,常用的就有四个,分别是Floyd、dijkstra、bf 和spfa,在这里我们只学floyd和dijkstra,因为这两种算法的思想不仅能用在最短路上,在其他的时候也能用来偷分。另外两种算法选学,在处理特别复杂的图问题的时候,这两种算法因为更优的复杂度还是有很高的使用率的,不过学习的成本有点高,不适合初学。

零、存图

进行图论算法的第一步,就是把图存起来。存图的两种方式为邻接矩阵和邻接表。

邻接矩阵是建立一个二维数组,大小为所有点的数量+5,比如题目说有1000个点,那么就要int edge[1005][1005],以两个点为下标,存下两点之间的距离,比如3号点和5号点之间距离为10(也可能不是距离),那么就是edge[3][5] = 10; 这样当所有的点输入完毕,图就存进邻接矩阵了。邻接矩阵的缺点是浪费空间,如果点有100000个,全局变量都无法开这么大的二维数组。而就算能开,在以后的遍历中怕也是超时了,况且考虑到利用率,如果路没用那么复杂,这个二维数组中很多就没用上。优点是省时间,代码简单,想要找哪条路只需要知道两个点就行。

邻接表是用很多链表组成的,他把与一点相连的所有点的标号与之间的路程都存进以这个点为下表的链表里,比如有1000个点,那么就vector<edge> edges[1005],3号点和5号点之间的距离是10,那么就是

struct edge
{
    int to, cost;
}edges[1005];

edge a;
a.to = 5;
a.cost = 10;
edges[3].push_back(a);   //好好想一想如何运用控制变量,通过for循环把图存进去

邻接表好处是显而易见的,节省了很多空间,提高了内存的利用率,缺点也很明显,就是写代码的时候十分繁琐,需要反复练习。

一、Floyd算法

二、dijkstra算法

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!