博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Dijkstra标准模板
阅读量:5165 次
发布时间:2019-06-13

本文共 3378 字,大约阅读时间需要 11 分钟。

Dijkstra求最短路问题:单元求最短路,从任意点出发求得该点到达其他任意点的距离

Dijkstra其实是一种贪心策略,与出发点(即源点)所连接的点中找到距离最短的点(这个距离是源点到这个点的最短距离)再以这个点继续以这样的操作来找到最短距离的点(松弛操作)

Q:为什么离源点最近的那个节点与源点的连边是源点到那个节点的最短距离?

如下图:

 

A:根据图片我们可以得知如果这条边是源点到达该点的最短距离那一定是源点到达该点的最短距离,不管怎么用其他边去更新它都不如该边短.

Q:Dijkstra的贪心流程:

这里我们假设源点为点1.  节点间的距离为X(数字)。

由分步图我们可以得知与源点1相连的有点2和点3    这里我们就会有两个操作   1.确立源点的最短点;   2.松弛另一个或几个点.

由X(2),X(3)可以到达源点1 因为X(1—2)=1<X(1—3)=12,所以我门可以确定源点1到点2的最短距离为“1”  且  松弛点3即 dis[3]=12

这步我们可以获得 dis[2]=1(确定) dis[3]=12(未确定)。

 

下一步我们移步到点2(因为点2到源点的最短距离确定了因此由点2一定能更新出另一个最短点)由图得与点2相连的点有点3和点4,  因为X(2—3)=9>X(2—4)=3

所以同样的操作我们可以 确定点2到点4的距离为3,因为先前X(1—2)=1,X(2—4)=3所以X(1—4)=4(确定); 通过比较我们发现还可以松弛点3 X(1—3)=12>[X(1—2)=1+X(2—3)=9]即X(1—3)=10(未确定)

这步我们可以获得 dis[4]=4(确定) dis[3]=10(未确定)

 

步骤接下来也如此直到将n个节点全部进行n次操作那源点到每个节点的距离就确定了

代码:

DIjkstra部分:

void dijkstra(){    for(int k=1;k<=n;k++)    {        int minn=INF,pos;//贪心确定松弛点,并确定松弛点的坐标        for(int i=1;i<=n;i++)        {            if(!vis[i]&&dis[i]
dis[pos]+edges[pos][i])//更新dis值 dis[i]=dis[pos]+edges[pos][i]; } } return;}

代码解释

先由源点松弛节点再在被松弛的节点中找到最小的距源点最短点作为下一个松弛点且确定此点到源点的距离最短下次不需要再被松弛因此将此点vis[pos]=true;不必再对此点进行操作

第一部分:

for(int k=1;k<=n;k++){    int minn=INF,pos;    for(int i=1;i<=n;i++)    {        if(!vis[i]&&dis[i]

 

第二部分:

for(int i=1;i<=n;i++){    if(!vis[i]&&dis[i]>dis[pos]+edges[pos][i])    dis[i]=dis[pos]+edges[pos][i];}//由于上一步将松弛点vis[pos]=true因此在此操作中if(!vis[i])即排除松弛点//并枚举1~n中可以被松弛的点,并对其进行松弛即dis[i]=dis[pos]+edges[pos][i]

关于dis[ i ]=dis[pos]+edges[pos][ i ]的解释

dis[pos]为松弛点在第一部分我们可以确定它的值,edges[pos][i]在输入时可以确定其值

所以当dis[i]>dis[pos]+edges[pos][i]时我们便可以松弛这个点的值即可以求得dis[源点—i]的值

整体代码:

#include 
#include
#include
#include
using namespace std;typedef int insert;#define in cin#define out coutconst int INF=0x3f3f3f3f;const int N=500+50;insert n,m,x,y,z,dis[N],vis[N],edges[N][N];insert startpoint;void value(){ memset(edges,INF,sizeof(edges)); memset(dis,INF,sizeof(dis)); for(int i=1;i<=m;i++) { in>>x>>y>>z; edges[x][y]=z; } dis[startpoint]=0; return;}void dijkstra(){ for(int k=1;k<=n;k++) { insert minn=INF,pos; for(int i=1;i<=n;i++) { if(!vis[i]&&dis[i]
dis[pos]+edges[pos][i]) dis[i]=dis[pos]+edges[pos][i]; } } return;}int main(){ in>>n>>m>>startpoint; value(); dijkstra(); for(int i=1;i<=n;i++) out<
<<"-->"<
<<" "<
<

 

#include 
#include
#include
#include
#include
#include
using namespace std;#define in cin#define out couttypedef long long insert;const int N=2e5+200;const int INF=0x3f3f3f3f;insert startpoint,n,m,x,y,z,dis[N];bool vis[N];struct Node { insert to,w;};vector
vt[N];void inital_value(){ for(int i=1;i<=m;i++) { in>>x>>y>>z; struct Node now; now.to=y;now.w=z; vt[x].push_back(now); } memset(dis,INF,sizeof(dis)); dis[startpoint]=0; return;}void dijkstra(){ for(int k=1;k<=n;k++) { insert minn=INF,pos; for(int i=1;i<=n;i++) { if(!vis[i]&&dis[i]
dis[pos]+vt[pos][i].w) dis[vt[pos][i].to]=dis[pos]+vt[pos][i].w; } } return;}int main(){ in>>n>>m>>startpoint; inital_value(); dijkstra(); for(int i=1;i<=n;i++) out<
<<"-->"<
<<" "<
<<" "<

 

转载于:https://www.cnblogs.com/CCCPKeay/p/10287732.html

你可能感兴趣的文章
菜鸟“抄程序”之道
查看>>
Ubuntu下关闭防火墙
查看>>
TCP/IP 邮件的原理
查看>>
原型设计工具
查看>>
windows下的C++ socket服务器(4)
查看>>
css3 2d转换3d转换以及动画的知识点汇总
查看>>
【Java】使用Eclipse进行远程调试,Linux下开启远程调试
查看>>
对Vue为什么不支持IE8的解释之一
查看>>
计算机改名导致数据库链接的诡异问题
查看>>
Java8内存模型—永久代(PermGen)和元空间(Metaspace)(转)
查看>>
ObjectiveC基础教程(第2版)
查看>>
centos 引导盘
查看>>
Notes of Daily Scrum Meeting(12.8)
查看>>
Apriori算法
查看>>
onlevelwasloaded的调用时机
查看>>
求出斐波那契数组
查看>>
lr_start_transaction/lr_end_transaction事物组合
查看>>
CodeIgniter学习笔记(四)——CI超级对象中的load装载器
查看>>
.NET CLR基本术语
查看>>
ubuntu的home目录下,Desktop等目录消失不见
查看>>