Dijkstra算法 计算有向图的最短路径
Posted miaomiaolan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dijkstra算法 计算有向图的最短路径相关的知识,希望对你有一定的参考价值。
自然语言描述
-
定义三个数组,分别为
V:表示所有的顶点集 D:表示从起始点到其他各点的距离 S:为已求得的从源点出发的最短路径长度的顶点的集合
-
设v0为起始点,若与v0直接连接的vi,则记录其权值到D[i],否则记录∞到D[i];
-
循环下列语句直至V-S为空集:
(1)遍历D中的数据,若D[i]为最小值;记录vi到S中
(2)更新D中的数据(遍历vj∈(V-S), D[ j ] = MIN(D[ j ] , D[ i ] + D[vi到vj的距离] ));
伪代码
算法:Dijkstra(G,v)v是起始点
输入:G=(V,E)是带权连通图
输出:D是含有起始点v到各点最短距离的数组
过程:
#define INF 0x7f7f7f7f
S ← { }
for i ←1 to |V| :
D[i] = INF
for every vi in V except v:
D[i] = min{ 所有的E(v , vi)};
while(|V-S| != 0){
//遍历D中数据
vk = min{every D[i] in D};
S ← v[k]
//更新D中数据
for every D[i] in D:
D[i] = min{D[i], D[k] + E(k,i) };
}
输出D
问题
Problem
Given a directed graph, compute all the shortest paths from the source to other vertices.
Input
The first line is the number of test cases.
For every test case, the first line is the number of node n, meaning nodes are 1,2,…,n.
The next line is the number of edges m, then m lines are followed, where each line is in the form of u v w, meaning (u,v) is an edge and it has weight w (>0).
The last line is the source vertex.
Output
For each test case, print all the shortest paths from the source s to other vertices (if the shortest path is finite) in the order of vertices in the following form (no spaces between):
s-1:d1
s-2:d2
…
Sample Input
2
2
1
1 2 5
1
5
6
1 2 4
1 3 6
2 3 1
4 5 1
3 1 1
5 4 2
2
Sample Output
1-1:0
1-2:5
2-1:2
2-2:0
2-3:1
代码实现
#include <stdio.h>
#define INF 0x7f7f7f7f
#define SIZE 100
void Dijkstra(int matrix[][SIZE],int vertex, int dis[],int startingpoint);
int min(int a, int b)return a>b?b:a;
int mindis(int dis[],int vertex,int usedvertex[]);
int main(){
int times; //次数
scanf("%d",×);
for(int t = 0; t < times; t++){
int vertex = 0; // 点数
int edge = 0; // 边数
scanf("%d",&vertex);
scanf("%d",&edge);
int matrix[SIZE][SIZE];
for(int i = 0; i <= vertex; i++){
for(int j = 0; j <= vertex; j++){
matrix[i][j] = INF;
}
}
//输入矩阵
for(int i = 0; i < edge; i++ ){
int x,y,weight;
scanf("%d",&x);
scanf("%d",&y);
scanf("%d",&weight);
if(weight < matrix[x][y]){
matrix[x][y] = weight;
}
}
int startingpoint;
scanf("%d",&startingpoint);
//distance 数组
int dis[vertex+1] ={0};
for(int i = 1; i <= vertex; i ++){
dis[i] = matrix[startingpoint][i];
}
//Dijkstra
Dijkstra(matrix,vertex,dis,startingpoint);
//输出
for(int i = 1; i <= vertex; i++){
if(dis[i]!=INF)printf("%d-%d:%d
",startingpoint,i,dis[i]);
}
}
}
//返回dis数组里的未被记录的最小值
int mindis(int dis[],int vertex,int usedvertex[]){
int min=INF, minvertex;
for(int i = 1 ; i <= vertex; i++){
if(usedvertex[i]==1)continue;
if(dis[i]<min){
min = dis[i];
minvertex = i;
}
}
return minvertex;
}
void Dijkstra(int matrix[][SIZE],int vertex, int dis[],int startingpoint){
int usedvertex[vertex+1] = {0}; //记录已确定最小值的点
int count = vertex-1;
usedvertex[0] = 1;
usedvertex[startingpoint] = 1;
while(count !=0 ){
//第一步,取新的点
int newvertex = mindis(dis,vertex,usedvertex);
usedvertex[newvertex] = 1;
//第二部,更新距离数组
for(int i = 1; i <= vertex; i++){
dis[i] = min(dis[i],matrix[newvertex][i]+dis[newvertex]);
}
count --;
}
dis[startingpoint] = 0;
}
以上是关于Dijkstra算法 计算有向图的最短路径的主要内容,如果未能解决你的问题,请参考以下文章