#返回上一级

@Author: 张海拔

@Update: 2015-03-11

@Link: http://www.cnblogs.com/zhanghaiba/p/3514570.html

Dijkstra算法

总的来说:算法从开始节点,按照总路径权值非递减的顺序去搜索所有路径,直到发现指定的终止节点或发现全部节点为止。

——我们先看看算法的步骤:

算法是递推的
先设d[begin] = 0, d[others] = INF
for [0, n)
1、未标记的节点中,选出当前d值最小的 (最快logn效率)
2、标记节点i
3、据节点i,若d[i] + w[i][j] < d[j],则更新d[j](d[j]可能变小,O(n)效率)

——我们再看看为什么这样做

循环每一步能确定以i节点为终点的最短路径(定义这种节点为:“最短路终点”)
而且很关键的一点是,这个最短路径终点的d值是最小递增或者说一定是非递减的

也就是上面说的“按照总路径权值非递减的顺序去搜索所有路径”

另外,d值的意义是:当前状态下,以该节点为终点的最短路径长度

假定A是起点,显然是A为终点的最短路径,d值是0

后续步骤中都是从已确定最短路终点集合中,递推出下一个最短路终点

想想最简单的情况
A只能到B和C和D,AB边长5,AC边长3,AD边长4
当前最短路终点集合只有A,集合一步可达的节点有B C D
它们目前的d值分别是5 3 4
把最小d值的C纳入最短路终点集合,因为它的d值无法变得更小,也就是说从当前状态往后这个节点的d值都是确定的

为什么呢?
把C纳入最短路终点集合,若CB边长是1,则会修改B的d值变为4,所以非最小值d值的节点,其d值可能会变得更小
反过来,若纳入其它任何节点到最短路终点集合,都不可能使其d值变得更小
因为不会出现 dNonMin + edge < dMin 的情况
后续情况同理类推

所以原理就是:

根据已经最短路终点集合来递推下一个最短路终点

过程使最短路终点集合一步可达的那些节点的d值不断减小

直到某节点d值无法减小,则纳入最短路终点集合

代码实现:

 /*
*Author: ZhangHaiba
*Date: 2014-1-10
*File: dijkstra.c
*
*dijkstra's algorithm demo
*/ #include <stdio.h>
#include <string.h>
#define N 512
#define INF 0x7fffffff; void dijkstra(int, int);
void print_path(int, int);
void set_mat(int);
void show_mat(int); int mat[N][N];
int vis[N];
int d[N];
int par[N]; int main(void)
{
int n; scanf("%d", &n);
set_mat(n);
//according to the question descript, begin=0, end=1
int begin_v = , end_v = ; dijkstra(begin_v, n);
//print path: begin:0, end:par[1]
print_path(begin_v, par[end_v]);
printf("%d\n", end_v);
printf("%d\n", d[end_v]);
return ;
} void dijkstra(int begin, int n)
{ int t, i, min, x, y; //init
memset(vis, , sizeof vis);
for (i = ; i < n; ++i)
d[i] = INF;
d[begin] = ;
par[begin] = begin; //loop n times
for (t = ; t < n; ++t) {
//choice min d[i]
min = INF;
for (i = ; i < n; ++i)
if (!vis[i] && d[i] < min)
min = d[x = i]; vis[x] = ; //update
for (y = ; y < n; ++y)
if (mat[x][y] > && d[y] > d[x] + mat[x][y]) {
d[y] = d[x] + mat[x][y];
par[y] = x;
}
}
} void print_path(int begin, int i)
{
if (i != begin)
print_path(begin, par[i]);
printf("%d ", i);
} void set_mat(int n)
{
int i, j; for (i = ; i < n; ++i)
for (j = ; j < n; ++j)
scanf("%d", &mat[i][j]);
} void show_mat(int n)
{
int i, j; for (i = ; i < n; ++i)
for (j = ; j < n; ++j)
printf(j == n- ? "%d\n" : "%d ", mat[i][j]);
}

测试用例

输入:
5
0 100 0 30 10
0 0 0 60 0
0 10 0 0 0
0 0 20 0 0
0 0 50 0 0

输出
0 3 2 1
60

#返回上一级

单源最短路(Dijkstra算法)的更多相关文章

  1. 单源最短路dijkstra算法&&优化史

    一下午都在学最短路dijkstra算法,总算是优化到了我能达到的水平的最快水准,然后列举一下我的优化历史,顺便总结总结 最朴素算法: 邻接矩阵存边+贪心||dp思想,几乎纯暴力,luoguTLE+ML ...

  2. 单源最短路——dijkstra算法

    Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止. 问 ...

  3. 单源最短路Dijkstra算法——matlab实现

    迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止. 基本思想 通过Dijk ...

  4. 单源最短路-dijkstra算法(未优化)

    bool used[maxn]; int g[maxn][maxn]; // 边未联系的填充为INF int d[maxn]; void dijkstra(int s){ memset(g,false ...

  5. 单源最短路径(dijkstra算法)php实现

    做一个医学项目,当中在病例评分时会用到单源最短路径的算法.单源最短路径的dijkstra算法的思路例如以下: 如果存在一条从i到j的最短路径(Vi.....Vk,Vj),Vk是Vj前面的一顶点.那么( ...

  6. 【算法】单源最短路——Dijkstra

    对于固定起点的最短路算法,我们称之为单源最短路算法.单源最短路算法很多,最常见的就是dijkstra算法. dijkstra主要用的是一种贪心的思想,就是说如果i...s...t...j是最短路,那么 ...

  7. 利用分支限界法求解单源最短路(Dijkstra)问题

    分支限界法定义:采用Best fist search算法,并使用剪枝函数的算法称为分支界限法. 分支限界法解释:按Best first的原则,有选择的在其child中进行扩展,从而舍弃不含有最优解的分 ...

  8. 单源最短路——Bellman-Ford算法

    1.Dijkstra的局限性 Dijkstra算法是处理单源最短路径的有效算法,但它局限于边的权值非负的情况,若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的. 列如以 ...

  9. 牛客编程巅峰赛S1第6场 - 黄金&钻石&王者 C.星球游戏 (单源最短路,Dijkstra)

    题意:有\(n\)个点,\(m\)条双向边,两个方向的权值都是相等的,可以从\(A\)中的某个点出发走到\(B\)中的某个点,求所有路径中的最短距离,如果A和B中没有点联通,则输出\(-1\). 题解 ...

随机推荐

  1. 375. 猜数字大小 II leetcode java

    题目: 我们正在玩一个猜数游戏,游戏规则如下: 我从 1 到 n 之间选择一个数字,你来猜我选了哪个数字. 每次你猜错了,我都会告诉你,我选的数字比你的大了或者小了. 然而,当你猜了数字 x 并且猜错 ...

  2. 关于Mybatis 反向生成后 查询结果全部为null 解决办法

    今天遇到了一个问题,就是mybatis通过反向生成工具 生成的pojo类(实体类) xml文件 以及Mapper之后查询时结果为null 我写的代码怎么看都没有错 就是没有结果 后来在排除错误的时候发 ...

  3. Windows安装Node.js报错:2503、2502的解决方法

    以管理员身份用msiexec安装 1.以管理员身份运行cmd命令 (Win + X, A) 以管理员身份运行cmd 2.cd到自己msi路径  用msiexec安装 用msiexec安装nodejs

  4. Linux下查找命令

    在CentOs下查找某个目录下的某个文件,使用如下指令: find /目录 -name 文件名 eg:查找当前目录下关于hadoop的文件 find / -name hadoop

  5. WebStorm 简单部署服务器进行测试操作

    WebStorm 简单部署服务器对外发布接口 第一步: 查看webstorm防火墙是否允许链接,控制面板-->防火墙-->高级设置 入站规则-->webstrom是否允许链接 ,双击 ...

  6. docker 实例设置自动重启

    yaml格式太严格了,每个冒号后面都必须带有空格在linux中./代表当前目录,属于相对路径../代表上一级目录,属于相对路径/代表根目录,/开头的文件都是绝对路径./configure的意思是执行当 ...

  7. POJ3460 Booksort(IDA*)

    POJ3460 Booksort 题意:给定一个长度为n的序列,每次可以取出其中的一段数,插入任意一个位置,问最少需要几次操作才能使整个序列变为1~n 思路:IDA*+迭代加深搜索 小技巧:将一段数插 ...

  8. How to manage local libraries in IntelliJ IDEA

    如何在 IntelliJ IDEA 中管理本地类库 一般来说,如果项目是基于 Maven 管理工具的,我们会在 pom.xml 中添加 dependency 来管理依赖.但有时也会遇到要用的类库不在 ...

  9. ubuntu16.04 安装 mysql-level

    ubuntu16.04 安装 mysql-level 1.下载 mysql-level(直接去官网下载rpm包,我的mysql-server是5.7.9.你下载自己对应的就可以了) 下载连接 2.rp ...

  10. 前端知识总结--BFC

    Block Formatting Context,中文直译为块级格式上下文. 1. BFC的定义 是 W3C CSS 2.1 规范中的一个概念,它决定了元素如何对其内容进行定位,以及与其他元素的关系和 ...