图中最短路径的三种求法

//Floyd算法
在这里插入图片描述
傻子也能看懂的弗洛伊德算法

//dijkstra算法
在这里插入图片描述
基本事实:
由于小根堆的存在,每次到达某顶点x时,dis[x]一定是最小的值,也就是此时x一定在从起点s—x的最短路径上;
此处的到达指的是出队时的x,而遍历邻接顶点得到的dis[v[i]]暂时还不一定是最小,后续还可能会对它更新;

求最短路径即为对于当前路径长度的单调递增;每次都到达的点一定是比之前距离刚刚增加一点点的那个点,所以随着我们不断维护这个距离的单调递增,一旦找到了终点,最短距离就找到了。

变形:
在这里插入图片描述
在这里插入图片描述

此时到达的x一定是位于从s—x的路径上,且这条路径的最大权值最小;
有点类似于贪心或者说是对于所求目的的单调递增

对于变形的问题,即为对于当前路径中的最大权值的单调递增;我们要不断选择可以使得最大权值不增加或者增加最小的那个点,使得当前的最大权值在单调的慢慢的递增,直到找到了终点,那这条路径也找到了;

还有多种变形方法:
如果要求找到一条要求满足f(e1,e2,e3,e4…en)最小的路径;我们只需要在不断找边的时,使得f(e)函数单调递增,直到找到终点即可;

visit数组起到的作用:
当点x出队后,对其标记,防止其再次出队;
与基本事实相对应,当x出队时,此时的dis[x]即是对于x的最小距起点距离,但有可能存在环路使得后续重回绕回x,这样的距离一定不是最短的,所以为了摒弃这种情况,加上visit数组;
进一步想,若此时图中存在负边:
在这里插入图片描述
我们让距离单调递增:
dis[s]=0;
dis[x]=1;
dis[y]=2;
当y出队时,不对劲了,我们发现s–y--x的距离为-1比之前小;应当更新为最短距离,但是由于visit数组的存在,dis[x]虽然被更新,但是它不能再次出队,所以更新也就无意思,也就得不到真正的最短距离:
换句话说,当图中出现负边时,dis数组将没法满足单调递增的效果(因为会突然出现一个负数),所以dijkstra不适合负权图;

//如何写出最短路径:
根据基本事实,我们可以在出队的时候给pre数组赋值,用last保存上一个节点,pre[x]=last;得到路径时只需倒推pre[终点];

//当程序结束后,任意的dis[x]存的一定是x距离起点的最短距离吗?
如果退出循环条件为到达终点就break;则任意dis[i]的值不一定为最短路径;
但是若依靠队列为空退出循环,任意dis[i]的值一定为最短路径;

//针对此csp题目:
还可使用二分答案方法:
l=最小边 r=最大边;
mid=(l+r)/2;
void judge()
{
去掉比mid大的所有边;
判断当前的图是否存在一条从起点到终点的路径;
(bfs或者dfs)
}
//充分利用dis数组意义:
在这里插入图片描述
方法一:
因为只能用一张商业票,每张商业票有起点和终点;
分别对起点和终点使用dijkstra算法;
得到两个数组dis1[i] dis2[j];
分别表示i距离起点的距离和j距离终点的距离;
枚举所有的商业票:起点:u 终点:v 权值 w
所以总距离=dis1[u]+dis2[v]+w;
然后比一比就可以了;
方法二:
创建二维数组dis[n][2];
dis[i][0]表示i到起点还未使用商业票的最短距离;
dis[i][1]表示i到起点已经使用商业票的最短距离;
仍然是按照距离单调递增的顺序找新的节点,
若dis[x][1]==inf
即到x的这条路径还没走过商业线;
所以对它的邻接顶点赋值的时候要考虑商业线和经济线;
若dis[x][1]!=inf
即只能考虑经济线;
最终得到的min(dis[v][1],dis[v][0])即为答案;

//Bellman ford算法
在这里插入图片描述
在这里插入图片描述
//spfa算法放弃了最小堆这个数据结构,即不再单调递增距离;
所以可以处理负权图,但是while循环的遍历次数可能会增加;
标记数组判断也不一样————————待续

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值