Dijkstra算法 计算有向图的最短路径

天然语言描述

  1. 定义三个数组,分别为node

    V:表示全部的顶点集
    
    D:表示从起始点到其余各点的距离
    
    S:为已求得的从源点出发的最短路径长度的顶点的集合
  2. 设v0为起始点,若与v0直接链接的vi,则记录其权值到D[i],不然记录∞到D[i];算法

  3. 循环下列语句直至V-S为空集:数组

(1)遍历D中的数据,若D[i]为最小值;记录vi到S中spa

(2)更新D中的数据(遍历vj∈(V-S), D[ j ] = MIN(D[ j ] , D[ i ] + D[vi到vj的距离] ));code

伪代码

算法: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.orm

Input

The first line is the number of test cases.input

For every test case, the first line is the number of node n, meaning nodes are 1,2,…,n.it

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).io

The last line is the source vertex.ast

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",&times);
	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\n",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;
}
相关文章
相关标签/搜索