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最短路算法,它可以方便的求得任意两点的最短路径,这称为“多源最短 ...
随机推荐
- Lazarus解决含中文文件名或路径的使用问题
其实用lazarus很久(也不算久啦..),目前打算做完手头的最后一个小程序然后就转向c#窗体程序..之前用lazarus的时候出了很多问题,资料也不是很好找,所以这回把比较容易说的记下来省得忘掉 ...
- [一道搜狗输入法的面试题]C++转换构造函数和类型转换函数
今天面试遇到一道有关C++转换构造函数的题目,之前经常见到默认构造函数.拷贝构造函数.析构函数,但是从没听说过转换构造函数,隐式转换函数也是一样,C++的确是够博大精深的,学习之路很长啊! 其实我们已 ...
- SharedPreferences最佳实践
转:http://blog.csdn.net/xushuaic/article/details/24513599 笔记摘要:该文章是我在Android Weekly中看到的,以前也一直用SharedP ...
- Dnsmasq(局域网DNS,DHCP)
安装:yum -y install dnsmasq dnsmasq配置文件: /etc/dnsmasq.conf 默认指定DNS服务器(优先级)文件:/etc/resolv.conf 默认host ...
- c语言 选择排序
选择排序 // int array[] = {3, 2, 6, 9, 8, 5, 7, 1, 4}; // int count = sizeof(array) / sizeof(array ...
- Esxi主机虚拟机迁移注意事项
1. Esxi主机上的虚拟机迁移只能是低----->高,或版本一样的才能进行迁移 [如Esxi5.1---->Esxi5.5]ok, 而Esxi5.5----->Esxi5.1 no ...
- myeclipse 环境配置优化,不断跟新整理中
myeclipse 环境配置,不断跟新整理中1.General --->Workspace ---> UTF-8 工作环境编码2.General --->Editors --> ...
- 强大的DELPHI RTTI–兼谈需要了解多种开发语言
一月 27th, 2005 by 猛禽 风焱在<“18般武艺”?>中说到他碰上的被多种语言纠缠的问题.我在回复里说: 很多语言只要能看懂几分就行了,没必要每一种都精通 但是如果只会很少的一 ...
- poj2636---Electrical Outlets(插线板)
#include <stdio.h> #include <stdlib.h> int main() { int n,nc,i; scanf("%d",&am ...
- 梯度下降算法的一点认识(Ng第一课)
昨天开始看Ng教授的机器学习课,发现果然是不错的课程,一口气看到第二课. 第一课 没有什么新知识,就是机器学习的概况吧. 第二课 出现了一些听不太懂的概念.其实这堂课主要就讲了一个算法,梯度下降算法. ...