Dijkstra算法模拟讲解
dijkstra算法,是一个求单源最短路径算法
其算法的特点为:
层层逼进,有点类似宽度搜索的感觉
其需要的数据结构为:
int map[N][N] 所有点之间的权表
int dis[N]
所有点到源点的最短距离
int prev[N] 存储每个点的前一个经过的点,用于输出路径
int used[N] 用于存储已经求出最短路径的点
则总的点减去used中的点,为还没有找出最短路径的点
初始化时:map为实际存储的权,如果某一边没有,则设置为无穷大INF,自身设置0
dis为源点到该点的距离,如果没有,也设置为无穷大INF
prev,如果与源点相邻,则设置为源点,否则为0
used 除了源点外,其余全为0
第一次比较源点到其相邻的点,找出最短距离的点k,将其加入used[k] = 1;
比较与k相邻的点j到源点的距离,如果比(dis[k] + map[k][j])源点到k + k
到j点的距离大,那么更新dis[j] = dis[k] + map[k][j],并记录prev[j] = k,
表示j的前一个经过的点为k,再重复寻找其余的点到源点的最短距离,再把找到
的点加入used中,直到全部节点都加入used中时,最短路径已完毕。
具体实现如下:
/*
Filename:dijkstra.cpp
Author: xiaobing
E-mail: xiaobingzhang29@gmail.com
Date: 2013-08-30
*/
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<string.h>
#include<stack>
#define N 50
#define M 50
#define INF 0xfffffff
using namespace std;
/*
*dijkstra算法,是一个求单源最短路径算法
其算法的特点为:
层层逼进,有点类似宽度搜索的感觉
其需要的数据结构为:
int map[N][N] 所有点之间的权表
int dis[N] 所有点到源点的最短距离
int prev[N] 存储每个点的前一个经过的点,用于输出路径
int used[N] 用于存储已经求出最短路径的点
则总的点减去used中的点,为还没有找出最短路径的点
初始化时:map为实际存储的权,如果某一边没有,则设置为无穷大INF,自身设置0
dis为源点到该点的距离,如果没有,也设置为无穷大INF
prev,如果与源点相邻,则设置为源点,否则为0
used 除了源点外,其余全为0
第一次比较源点到其相邻的点,找出最短距离的点k,将其加入used[k] = 1;
比较与k相邻的点j到源点的距离,如果比(dis[k] + map[k][j])源点到k + k
到j点的距离大,那么更新dis[j] = dis[k] + map[k][j],并记录prev[j] = k,
表示j的前一个经过的点为k,再重复寻找其余的点到源点的最短距离,再把找到
的点加入used中,直到全部节点都加入used中时,最短路径已完毕。 */ /*
*dijkstra算法
*@node 总共的节点数
*@from 源点
*@map 点与点之间的权表
*@dis 源点到该点的最短距离
*@prev 存储当前的前一个经过的点
*/
void dijkstra(int node, int from, int map[][N], int dis[], int prev []){
int i,j,k;
//初始化为所有节点均为求出最短路径
int used[N] = {0};
//第一个点已使用,并且已求出
used[from] = 1;
//初始化源点到其他点的距离
for(i = 1;i <= node;i++){
dis[i] = map[from][i];
//如果源点到该点不可达,那么其前经过的点为0
//相反为from
if(dis[i] == INF || dis[i] == 0){
prev[i] = 0;
} else {
prev[i] = from;
}
}
int min;
//遍历node次,寻找每个点到源点的最短距离
for(i = 1;i <= node;i++){
//初始化为无穷大
min = INF;
//遍历其他没有加入used中的点,并找出最短路径的点k
for(j = 1;j <= node;j++){
if(!used[j] && dis[j] < min){
min = dis[j];
k = j;
}
} //将该点加入used中,表示已求出从源点到该点的最短路径
used[k] = 1; //更新与k相邻的点到源点的距离
//如果经过k点到j的距离更短,那么更新dis[j](从源点到j的距离)
//为源点到k的距离 + k到j的距离,即:dis[k] + map[k][j]
//并更新j的前一个经过的点为k
for(j = 1;j <= node;j++){
if(dis[j] > dis[k] + map[k][j]){
dis[j] = dis[k] + map[k][j];
prev[j] = k;
}
}
}
} //打印二维表
void print(int table[][M], int row, int col){
int i,j;
for(i = 0;i < row;i++){
for(j = 0;j < col;j++){
cout<<table[i][j]<<" ";
} cout<<endl;
}
} //打印路径,由于是一个点储存才是前置节点,可以用栈来存储
//from 为源点
//to 为目的点
//prev 为前置节点路径
void printPath(int from, int to, int prev[]){
stack<int> path;
//把目标点入栈
path.push(to);
//一直找到源点,当然,也可能没有源点,但那个点的前置节点为0
//这里需要防止环路,所以可以用距离来判断,当相等时,就退出了
while(prev[to] != 0){
path.push(prev[to]);
to = prev[to]; }
//如果栈顶节点不是源点,说明从源点到目标点不可达
if(path.top() != from){
cout<<"没有路径"<<endl;
return ;
} cout<<"路径为: "; int flag = 0; //第一次不输出指标
while(!path.empty()){
if(flag)
cout<<"->";
flag = 1;
cout<<path.top();
path.pop();
}
cout<<endl;
}
int main(){
int i, j;
//定义一个权表
int map[N][M];
//初始化map为INF
for(i = 0;i < N;i++){
for(j = 0;j < M;j++){
map[i][j] = INF;
if(i == j){
map[i][j] = 0;
}
}
}
//print(map, N, M);
//node 节点数
//line 边数
//start 源点
int node,line,start;
cin>>node;
cin>>line;
cin>>start; int from, to,len;
//接受数据并初始化map
for(i = 0;i < line;i++){
cin>>from>>to>>len;
map[from][to] = len;
}
cout<<endl;
cout<<"原始数据为:"<<endl;
print(map, node + 1, node + 1);
cout<<endl; //初始时所有的最短路径为0,前置节点为0
int dis[N] = {0};
int prev[N] = {0};
dijkstra(node, start, map, dis, prev);
for(i = 0;i <= node;i++){
cout<<prev[i]<<" ";
}
cout<<endl; cout<<"从节点"<<start<<"到其他节点的最短距离为:"<<endl; for(i = 1;i <= node;i++){
cout<<start<<"--"<<i<<"距离为:"<<dis[i]<<endl;
printPath(start, i, prev);
}
return 0;
}
测试数据为:
5
7
1
1 2 10
1 4 30
1 5 100
2 3 50
3 5 10
4 3 20
4 5 60 原始数据为:
0 268435455 268435455 268435455 268435455 268435455
268435455 0 10 268435455 30 100
268435455 268435455 0 50 268435455 268435455
268435455 268435455 268435455 0 268435455 10
268435455 268435455 268435455 20 0 60
268435455 268435455 268435455 268435455 268435455 0 0 0 1 4 1 3
从节点1到其他节点的最短距离为:
1--1距离为:0
路径为: 1
1--2距离为:10
路径为: 1->2
1--3距离为:50
路径为: 1->4->3
1--4距离为:30
路径为: 1->4
1--5距离为:60
路径为: 1->4->3->5 ===================================== 5
7
5
1 2 10
1 4 30
1 5 100
2 3 50
3 5 10
4 3 20
4 5 60 原始数据为:
0 268435455 268435455 268435455 268435455 268435455
268435455 0 10 268435455 30 100
268435455 268435455 0 50 268435455 268435455
268435455 268435455 268435455 0 268435455 10
268435455 268435455 268435455 20 0 60
268435455 268435455 268435455 268435455 268435455 0 0 0 0 0 0 0
从节点5到其他节点的最短距离为:
5--1距离为:268435455
没有路径
5--2距离为:268435455
没有路径
5--3距离为:268435455
没有路径
5--4距离为:268435455
没有路径
5--5距离为:0
路径为: 5
=====================================
原始数据为:
0 268435455 268435455 268435455 268435455 268435455
268435455 0 40 10 268435455 268435455
268435455 268435455 0 10 30 50
268435455 268435455 80 0 20 40
268435455 268435455 268435455 268435455 0 10
268435455 268435455 268435455 268435455 268435455 0 0 0 0 2 2 4
从节点2到其他节点的最短距离为:
2--1距离为:268435455
没有路径
2--2距离为:0
路径为: 2
2--3距离为:10
路径为: 2->3
2--4距离为:30
路径为: 2->4
2--5距离为:40
路径为: 2->4->5
Dijkstra算法模拟讲解的更多相关文章
- Kruskal算法模拟讲解
Kruskal 算法是一个求最小生成树的算法,即求最小的开销等 算法可以这样,要求得最小生成树,那么n个节点只能包括n-1条边 所以我们应该转换为寻找这最短的n-1条边,因此,可以先对所有的 边进行从 ...
- 三角网格上的寻路算法Part.1—Dijkstra算法
背景 最近在研究中产生了这样的需求:在三角网格(Mesh)表示的地形图上给出两个点,求得这两个点之间的地面距离,这条距离又叫做"测地线距离(Geodesic)".计算三角网格模型表 ...
- 数据结构--Dijkstra算法最清楚的讲解
迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径.它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止 ###基本思想 通过Dij ...
- 7-11 社交网络图中结点的“重要性”计算 (30 分)(Dijkstra算法)
题意: 思路:对每个输入的点跑一遍dijkstra算法,然后对这个点到所有点的距离求和按公式输出就可以了. (这次尝试了用数组模拟链表来做最短路问题,刷新了自己对最短路的理解) 这里构造链表的过程我 ...
- [图论]Dijkstra 算法小结
Dijkstra 算法小结 By Wine93 2013.11 1. Dijkstra 算法相关介绍 算法阐述:Dijkstra是解决单源最短路径的算法,它可以在O(n^2)内计算出源点(s)到图中 ...
- Cocos2d-x 地图步行实现1:图论Dijkstra算法
下一节<Cocos2d-x 地图行走的实现2:SPFA算法>: http://blog.csdn.net/stevenkylelee/article/details/38440663 本文 ...
- 单源最短路径问题之dijkstra算法
欢迎探讨,如有错误敬请指正 如需转载,请注明出处 http://www.cnblogs.com/nullzx/ 1. 算法的原理 以源点开始,以源点相连的顶点作为向外延伸的顶点,在所有这些向外延伸的顶 ...
- 最小生成树(prime算法 & kruskal算法)和 最短路径算法(floyd算法 & dijkstra算法)
一.主要内容: 介绍图论中两大经典问题:最小生成树问题以及最短路径问题,以及给出解决每个问题的两种不同算法. 其中最小生成树问题可参考以下题目: 题目1012:畅通工程 http://ac.jobdu ...
- (转)最短路算法--Dijkstra算法
转自:http://blog.51cto.com/ahalei/1387799 上周我们介绍了神奇的只有五行的Floyd最短路算法,它可以方便的求得任意两点的最短路径,这称为“多源最短 ...
随机推荐
- SSDT表详解
SSDT(system service dispatch table) 系统服务分派表 SSPT(system service parameter table) 系统服务参数表 #pragma pac ...
- [php]php时间戳当中关于时区的问题
PHP_VERSION = 5.5.11 话说php函数 time() 的起始时间戳是从:GMT 1970-01-01 00:00:00 开始算起的 写了点测试代码: $gmt1 = strtotim ...
- js-计算器
<div class="main"><h1>HTML5-计算器</h1> <input id="num1& ...
- 求一个int型整数的两种递减数之和(华为2015笔试题及答案)
给出一个整数(负数使用其绝对值),输出这个整数中的两种递减数(1.最大递减数:2.递减数中各位数之和最大的数)之和. 递减数:一个数字的递减数是指相邻的数位从大到小排列的数字,不包含相邻的数位大小相同 ...
- 【翻译】MVC Music Store 教程-概述(三)
Controller 与传统的Web框架,将传入的URL通常映射到磁盘上的文件.例如:一个URL请求“/Products.aspx" 或"/Products.php”是处理一个Pr ...
- eclipse中使用EasyExplorer插件定位文件 [转载]
如果你经常需要在Eclipse里打开相关资源文件所在的文件夹,比较麻烦,要右键,属性,在Location一栏中把所在的文件夹拷贝一下,然后再去资源管理器里输入这个路径,回车,打开它. 解决方法: 用E ...
- startup_LPC17XX.s 启动文件分析
工程中startup_LPC17XX.s是M3的启动文件,启动文件由汇编语言写的,它的作用一般是下面这几个: 1)堆和栈的初始化 2)中断向量表定义 3)地址重映射及中断向量表的转移 4)设置系统时钟 ...
- Android LocalActivityManager的用法
在开发中会碰到在一个activity中的局部(或者是activity的Fragment中)显示其他的activity 的内容,这时就用到了LocalActivityManager类. 假设这个容器是一 ...
- 跟我一起学ruby (转)
跟我一起学ruby By Tiger 注:本教程转载自在游戏先行者论坛,版权属于作者Tiger. 第一篇 第二篇 第一篇 自序 从今天起我就要开始学Ruby了.怎么样,没见吧?一个新人写教程.就凭我坚 ...
- Error copying image in the datastore: Not allowed to copy image file
opennebula error copying image in the datastore not allowed to copy image file Error copying image i ...