图中最短路径算法(Dijkstra算法)(转)

1.Dijkstra

1)      适用条件&范围:

a)   单源最短路径(从源点s到其它所有顶点v);

b)   有向图&无向图(无向图可以看作(u,v),(v,u)同属于边集E的有向图)

c)   所有边权非负(任取(i,j)∈E都有Wij≥0);

2)      算法描述:

在带权图中最常遇到的问题就是,寻找两点间的最短路径问题。

解决最短路径问题最著名的算法是Djikstra算法。这个算法的实现基于图的邻接矩阵表示法,它不仅能够找到任意两点的最短路径,还可以找到某个指定点到其他所有顶点的最短路径。

此算法的基本思想是:

1>选中指定的顶点,列出此顶点到其他的顶点的权值,不相邻的为无穷大

2>从以上权值中选出最小值,此最小值就是起始点到对应顶点的最短路径,并标记这个对应顶点

3> 将起始点到其他未标记的顶点的直接距离与起始点到刚才标记顶点加上标记顶点到其他顶点距离的和比较,如果     后者小,则更新对应的权值。

4> 转2

程序代码如下:

#include <iostream>

#include <iomanip>

using namespace std;

#include "Graph.h"

void main()

{

int i, n;

cout << "输入你所输入的有向带权图的顶点个数: ";

cin >> n;

adjmatrix g;

InitMatrix(g);

CreateMatrix(g);

cout << "你输入的有向带权图的邻接矩阵表示为: " << endl;

PrintMatrix(g, n);

int * d = new int [n];

edgenode ** path = new edgenode * [n];

cout << "请输入你要输入的源点: ";

cin >> i;

Dijkstra(g, d, path, i, n);

PrintPath(d, path, i, n);

}

//***********Graph.h**********************

#define MaxVerNum 20

#define MaxValue 10000

typedef int adjmatrix[MaxVerNum][MaxVerNum];     //邻接矩阵的类型定义

typedef struct Node

{

int adjvex;

struct Node * next;

}edgenode;        //指针数组path[]基类型定义

//初始化邻接矩阵表示的有向带权图

void InitMatrix(adjmatrix G)

{

int  i, j;

for(i = 0; i < MaxVerNum; i++)

for(j = 0; j < MaxVerNum; j++)

G[i][j] = MaxValue;

}

//建立邻接矩阵表示的有权带向图(即通过输入图的每条边建立图的邻接矩阵)

void CreateMatrix(adjmatrix G)

{

int i, j, x;

cout << "请输入顶点和相应的权值: " << endl;

cin >> i >> j >> x;

while(i != -1)

{

G[i][j] = x;

cin >> i >> j >> x;

}

}

//输出邻接矩阵表示的有向带权图(即输出图的每条边)

void PrintMatrix(adjmatrix G, int n)

{

int i, j;

for(i = 0; i < n; i++)

{

for(j = 0; j < n; j++)

{

if(G[i][j] == MaxValue)

cout << setiosflags(ios::left) << setw(5) << "Inf";

else

cout << setiosflags(ios::left) << setw(5) << G[i][j];

}

cout << endl;

}

}

void Path(edgenode * path[], int m, int j)

{

edgenode * p, * q, *s;

p = path[j];

while(p != NULL)

{

path[j] = p->next;

delete p;

p = path[j];

}

p = path[m];

while(p != NULL)

{

q = new edgenode;

q->adjvex = p->adjvex;

if(path[j] == NULL)

path[j] = q;

else

s->next = q;

s = q;

p = p->next;

}

q = new edgenode;

q->adjvex = j;

q->next = NULL;

s->next = q;

}

//求最短路径的Dijkstral算法

void Dijkstra(adjmatrix GA, int dist[], edgenode *path[], int i, int n)

{

int j, k, w, m;

bool * s = new bool[n];

for(j = 0; j < n; j++)

{

if(j == i)

s[j] = true;

else

s[j] = false;

dist[j] = GA[i][j];

if(dist[j] < MaxValue && j != i)

{

edgenode * p1 = new edgenode;

edgenode * p2 = new edgenode;

p1->adjvex = i;

p2->adjvex = j;

p2->next = NULL;

p1->next = p2;

path[j] = p1;

}

else

path[j] = NULL;

}

for(k = 1; k <= n-2; k++)

{

w = MaxValue;

m = i;

for(j = 0; j < n; j++)

if(s[j] == false && dist[j] < w)

{

w = dist[j];

m = j;

}

if(m != i)

s[m] = true;

else

break;

for(j = 0; j < n; j++)

if(s[j] == false && dist[m] + GA[m][j] < dist[j])

{

dist[j] = dist[m]+GA[m][j];

Path(path, m, j);

}

}

delete []s;

}

//输出从源点到每个顶点的最短路径及长度的函数

void PrintPath(int dist[], edgenode * path[], int i, int n)

{

int j;

for(j = 0; j < n; j++)

{

if(i != j)

{

cout << "顶点v" << i << "到顶点v" << j << "的最短路径的长度为 "

<< dist[j] << ", 最短路径为: ";

edgenode * p = path[j];

while(p != NULL)

{

cout << setw(4) << p->adjvex;

p = p->next;

}

cout << endl;

}

}

}

程序运行结果:

输入你所输入的有向带权图的顶点个数: 6

请输入顶点和相应的权值:

0 1 10

0 2 12

1 3 16

1 4 25

2 0 4

2 1 3

2 3 12

2 5 8

3 4 7

5 3 2

5 4 10

-1 2 3

你输入的有向带权图的邻接矩阵表示为:

Inf  10   12   Inf  Inf  Inf

Inf  Inf  Inf  16   25   Inf

4    3    Inf  12   Inf  8

Inf  Inf  Inf  Inf  7    Inf

Inf  Inf  Inf  Inf  Inf  Inf

Inf  Inf  Inf  2    10   Inf

请输入你要输入的源点: 0

顶点v0到顶点v1的最短路径的长度为 10, 最短路径为: 0   1

顶点v0到顶点v2的最短路径的长度为 12, 最短路径为: 0   2

顶点v0到顶点v3的最短路径的长度为 22, 最短路径为: 0   2   5   3

顶点v0到顶点v4的最短路径的长度为 29, 最短路径为: 0   2   5   3   4

顶点v0到顶点v5的最短路径的长度为 20, 最短路径为: 0   2   5

Press any key to continue

转自:http://blog.sina.com.cn/s/blog_51b6521b0100k96c.html

时间: 2024-10-23 22:19:24

图中最短路径算法(Dijkstra算法)(转)的相关文章

python数据结构与算法——图的最短路径(Dijkstra算法)

1 # Dijkstra算法——通过边实现松弛 2 # 指定一个点到其他各顶点的路径——单源最短路径 3 4 # 初始化图参数 5 G = {1:{1:0, 2:1, 3:12}, 6 2:{2:0, 3:9, 4:3}, 7 3:{3:0, 5:5}, 8 4:{3:4, 4:0, 5:13, 6:15}, 9 5:{5:0, 6:4}, 10 6:{6:0}} 11 12 13 # 每次找到离源点最近的一个顶点,然后以该顶点为重心进行扩展 14 # 最终的到源点到其余所有点的最短路径 15

图的单源最短路径:Dijkstra算法实现

本文介绍的是图的非负权值的单源最短路径问题.问题的提出是,对于有权图D,t提供源点v,要找到从v到其他所有点的最短路径,即单源最短路径问题,在本文中,解决这一问题,是普遍比较熟悉的Dijkstra算法. 算法核心思想参见维基.简而言之,设集合S存放已经求出了最短路径的点.初始状态S中只有一个点v0,之后每求得v0到vn的最短路径,就会更新v0到所有vn邻接的点的一致的最短路径(不一定是最终的最短路径),如此重复,每次会确定v0到一个点的最短路径,确定好的点加入S中,直至所有点进入S结束.在本文中

最短路径算法-Dijkstra算法的应用之单词转换(词梯问题)

一,问题描述 在英文单词表中,有一些单词非常相似,它们可以通过只变换一个字符而得到另一个单词.比如:hive-->five:wine-->line:line-->nine:nine-->mine..... 那么,就存在这样一个问题:给定一个单词作为起始单词(相当于图的源点),给定另一个单词作为终点,求从起点单词经过的最少变换(每次变换只会变换一个字符),变成终点单词. 这个问题,其实就是最短路径问题. 由于最短路径问题中,求解源点到终点的最短路径与求解源点到图中所有顶点的最短路径复

最短路径之Dijkstra算法

Dijkstra算法: 首先,引进一个辅助向量D,它的每个分量D[i]表示当前所找到的从始点v到每个终点vi的的长度:如D[3]=2表示从始点v到终点3的路径相对最小长度为2.这里强调相对就是说在算法过程中D的值是在不断逼近最终结果但在过程中不一定就等于长度.它的初始状态为:若从v到vi有弧,则D为弧上的权值:否则置D为∞.显然,长度为 D[j]=Min{D | vi∈V} 的路径就是从v出发的长度最短的一条.此路径为(v,vj). 那么,下一条长度次短的是哪一条呢?假设该次短路径的终点是vk,

单源点最短路径的Dijkstra算法

在带权图(网)里,点A到点B所有路径中边的权值之和为最短的那一条路径,称为A,B两点之间的最短路径;并称路径上的第一个顶点为源点(Source),最后一个顶点为终点(Destination).在无权图中,最短路径则是两点之间经历的边数最少的路径.实际上,只要把无权图上的每条边都看成是权值为1的边,那么无权图和带权图的最短路径是一致的. 给定一个带权有向图G=(V,E),指定图G中的某一个顶点的V为源点,求出从V到其他各顶点之间的最短路径,这个问题称为单源点最短路径问题. 迪杰斯特拉(Dijkst

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

做一个医学项目,其中在病例评分时会用到单源最短路径的算法.单源最短路径的dijkstra算法的思路如下: 如果存在一条从i到j的最短路径(Vi.....Vk,Vj),Vk是Vj前面的一顶点.那么(Vi...Vk)也必定是从i到k的最短路径.Dijkstra是以最短路径长度递增,逐次生成最短路径的算法.例如:对于源顶点V0,首先选择其直接相邻的顶点中长度最短的顶点Vi,那么当前已知可得从V0到达Vj顶点的最短距离dist[j]=min{dist[j],dist[i]+cost[i][j]}.假设G

hdu 2680 最短路径(dijkstra算法+多源最短路径单源化求最小值)

Choose the best route Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7062    Accepted Submission(s): 2301 Problem Description One day , Kiki wants to visit one of her friends. As she is liable

最短路算法 :Bellman-ford算法 &amp; Dijkstra算法 &amp; floyd算法 &amp; SPFA算法 详解

 本人QQ :2319411771   邮箱 : [email protected] 若您发现本文有什么错误,请联系我,我会及时改正的,谢谢您的合作! 本文为原创文章,转载请注明出处 本文链接   :http://www.cnblogs.com/Yan-C/p/3916281.html . 很早就想写一下最短路的总结了,但是一直懒,就没有写,这几天又在看最短路,岁没什么长进,但还是加深了点理解. 于是就想写一个大点的总结,要写一个全的. 在本文中因为邻接表在比赛中不如前向星好写,而且前向星效率并

有向有权图的最短路径算法--Dijkstra算法

Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijkstra算法是很有代表性的最短路径算法, 在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等.注意该算法要求图中不存在负权边. 问题描述:在无向图 G=(V,E) 中,假设每条边 E[i] 的长度为 w[i],找到由顶点 V0 到其余各点的最短路径.(单源最短路径) 2.算