自然語言描述
-
定義三個陣列,分別為
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\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;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/27316.html
標籤:C
上一篇:C 實戰練習題目12
下一篇:C 實戰練習題目13 -水仙花數
