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;
}
相關文章
相關標籤/搜索