博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
图的那些事儿——Dijkstra和Floyd
阅读量:5772 次
发布时间:2019-06-18

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

最短路问题

Dijkstra算法

说到最短路问题,我相信只要是学习过计算机的人都有听说过Dijkstra他老人家,他对程序的贡献远不止一个算法。

1 提出“goto有害论”;

2 提出信号量和PV原语;
3 解决了“哲学家聚餐”问题;
4 最短路径算法(SPF)和银行家算法的创造者;
5 第一个Algol 60编译器的设计者和实现者;
6 THE操作系统的设计者和开发者;

按照他自己的称呼,他是一个程序员。不得不说,这样的程序员实在是太伟大了。

让我们回到Dijkstra算法上。

这个算法的核心是维护d[i]=>i号结点和起点s距离的估值,之所以是估值,是因为它可能并不是真的最短值。要经历一个过程,才能够成为真正的最短值。

这次我们先看算法好了。

清除所有点的标号(所有点都是未知的)设d[0]=0,d[i]=INF(无限大)循环n次{    #在未知的点中,寻找出d值最小的结点x    *标记x为已知    对于从x出发的所有边(x,y)更新 d[y]=min(d[y],d[x]+w[x][y])   }

我们看到了这个过程(标了*号的这一行)。

是当d[x]为当前所有未知点中的最小值时,别的所有的到达x的走法都是绕远路、舍近求远。所以,这时我们可以确定 d[x]就是x点和起点s的最短距离!
我们来写一个简单的版本好了

//v 标记是否已知//memset(v,0,sizeof(v));for(int i=0;i

代码中带有注释的两处其实都可以优化。

查找最小结点这种工作其实对于一个优先队列来说非常合适。
这个队列中拥有d值以及其对应的结点号(d[i]和i)
还需要定义>操作符

struct HeapNode{    int d,i;    bool operator < (const HeapNode& rhs) const{        return d>rhs.d;     } }

在正式完成算法之前,我们首先对数据结构进行些许该进。另一个可以优化的地方也在这里,将w[i][j]这样一个N^2的数组转换为一个vector< int> Gi[maxn]来存储边号,用vector< Edge> Edges来存储边。

struct Edge{    int from,to;    int dist;    Edge(int x,int y,int d):from(u),to(v),dist(d){}}
struct Dijstra{    vector
G[maxn]; vector
edges; int m,n; int d[mniaxn],v[maxn]; int p[maxn];/*保存父结点*/ void init(int n){ this->n=n; for(auto item:G)item.clear(); edges.clear(); } void AddEdge(int from,int to,int dist){ edges.push_back(Edge(from,to,dist)); m=edges.size(); G[from].push_back(m-1);/*m-1刚好为这个边在edges中的索引*/ } void dijkstra(int s){ ... }}

主算法:

void Dijkstra(int s){    priority_queue
Q; for(int i=0;i
d[u]+e.dist){ d[e.to]=d[u]+e.dist; p[e.to]=G[u][i]; Q.push((HeapNode){d[e.to],e.to}) } } }}

是不是有点累了呢。没关系,只要看懂了第一段代码,对Dijkstra的贪心思想熟记于心就可以了!

但是Dijkstra算法在面对有负权边时就无能为力了,有负环的话就意味着最短路径不存在!
这个时候我们需要另一种算法Bellman-Ford算法
Bellman-Ford
我们先直接上代码看看

for(int i=0;i

需要指出的是:Bellman-Ford算法非常低,其优化这里先不给出

我们应该关注的重点在于Floyd算法:

for(int k=0;k

Floyd求出的是各个点对的距离。

版权声明:本文为博主原创文章,转载请标明出处。

转载于:https://www.cnblogs.com/fridge/p/4861900.html

你可能感兴趣的文章
CSS盒模型
查看>>
ng2路由延时加载模块
查看>>
使用GitHub的十个最佳实践
查看>>
全面了解大数据“三驾马车”的开源实现
查看>>
脱离“体验”和“安全”谈盈利的游戏运营 都是耍流氓
查看>>
慎用!BLEU评价NLP文本输出质量存在严重问题
查看>>
基于干净语言和好奇心的敏捷指导
查看>>
Node.js 2017企业用户调查结果发布
查看>>
“软”苹果水逆的一周:杂志服务崩溃,新机型遭泄露,芯片首架离职
查看>>
JAVA的优势就是劣势啊!
查看>>
ELK实战之logstash部署及基本语法
查看>>
帧中继环境下ospf的使用(点到点模式)
查看>>
BeanShell变量和方法的作用域
查看>>
LINUX下防恶意扫描软件PortSentry
查看>>
由数据库对sql的执行说JDBC的Statement和PreparedStatement
查看>>
springmvc+swagger2
查看>>
软件评测-信息安全-应用安全-资源控制-用户登录限制(上)
查看>>
cacti集成
查看>>
Android中的Cursor
查看>>
我的友情链接
查看>>