这周主要做了最短路径专题练习和对贪心的理解练习。关于对最小生成树的理解和应用在上周已经总结过了,这周主要总结总结最短路径。
首先最短路径指的就是两顶点之间经历的边上权值之和最短的路径。结合老师讲的课件和看的博客,总结了下面三个主要的算法。
一.Dijkstra
是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是从起始点开始,采用贪心算法的策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止。
具体步骤
1.初始化路径矩阵,所有两点之间的距离为边的权值,如果两点之间没有边相连,则权值无穷大。
2.从len数组选择最小值,则该值为当前源点到其他点的最短路径,并且把该点加入到path中,然后对其他点进行路径压缩。
3.重复步骤2。
MST = {s};
while (1) {
V = 未收录顶点中距离最小者;
if ( V不存在 )
break;
else
将V收录进MST;
V被收录;
for ( 每个点 W )
if ( W未被收录 )
if ( 最短路径到W的距离 <最短路径到V的距离 +V到W的距离 ){
最短路径到W的距离 <最短路径到V的距离 +V到W的距离 ;
记录W的前一个点位V;
}
}
参考题目:https://www.luogu.com.cn/problem/P1339
https://www.luogu.com.cn/problem/P1576
二、Floyd
是一种用于寻找给定的加权图中多源点之间最短路径的算法。
具体步骤:我们知道两个点的相连,有时是直接相连,有时是通过中间结点相连。此算法抓住这个特性,通过三轮循环:第一轮循环此次寻找的中间结点k、第二轮循环初始结点i、第三轮循环结尾结点j。用edge[i][j]存储权值,如果edge[i][j] > edge[i][k] + edge[k][j],那就说明之前i 和 j 之间的路径比这次的长,需要替换。
设E(u,v)为u点到v点的距离;
For(每一个点k)
For(每一个点i)
For(每一个点j)
IF(E(i,j)>E(i,k)+E(k,j))
E(i,j)=E(i,k)+E(k,j);
缺点是算法复杂度太大,一旦图的规模过大计算时间就会大大增加,在做题时也会出现超时的现象。
参考题目:https://www.luogu.com.cn/problem/P1690
https://www.luogu.com.cn/problem/P3905
三、spfa
优点:
1.时间复杂度比普通的Dijkstra和Ford低。
2.能够计算负权图问题。
3.能够判断是否有负环
具体步骤:1.设立一个先进先出的队列
2.每次取出队首元素,用队首元素到起点的最优值对与其相连的其他元素的到起点的最优值进行优化(a+b>c)正确性是显然的
3.当队列为空时及所有元素优化到不能再优化了,算法结束。
参考题目:https://www.luogu.com.cn/problem/P1744
https://www.luogu.com.cn/problem/P1938
这几道题都是这几种算法很好的应用,应该也是比较典型的,基本就是根据上面的步骤,我也是结合着自己的思想和题解一步步做出来了。
总结:
(1)确定起点的最短路径问题:即已知起始结点,求最短路径的问题。
(2)确定终点的最短路径问题:与确定起点的问题相反,该问题是已知终结结点,求最短路径的问题。在无向图中该问题与确定起点的问题完全等同,在有向图中该问题等同于把所有路径方向反转的确定起点问题。
(3)确定起点终点的最短路径问题:即已知起点和终点,求两结点之间的最短路径。
(4)全局最短路径问题:求图中所有的最短路径。
在做专题练习的时候,用到的基本都是上面这三种算法,很多可以用多种方法做,比如说p1396营救,可以用kruskal求最小生成树,当s和t连通时,此时边的权值w就是题中要求的最小的最大值(因为边是从小到大排序的),也可以用spfa求最短路。分析可知要让每段路的权值都尽可能小,所得到的路径不一定是人s到t的最短路,但是可以利用最短路的模板来解决:取两条边权值的较大者,如果比第三条边小,则更新。关于这部分题,看题解,说的最多的一段话就是:这是一道模版题,当然,有裸套模版的,但大部分题目是很有难度的,还有就是题目很长,但是思想很简单的,比如p2935,所以说,以后做题不能被题目吓到,一看到这么长的题干脆没怎么想就放弃了。总结一下,这些题要求的无非就是从A地区到B地区间的众多路径中,哪一条路径的路途最短。
还有就是贪心,主要应用就是针对一组数据,事先定义了限制值和期望值,希望从中选择几个数据,在满足限制的情况下,期望值最大。主要问题就是怎么去贪,说白了,就是考察思维,这部分难度依然很高,还需要下功夫。
浅总结一下这周,最短路径算是过去了,套个模版解决大部分问题,但整体难度还是很高,做完这部分专题自己也是又收获了很多,周六讲的贪心后面那几道题还是挺迷糊的,下周就是看贪心那几篇博客,继续加油。