1. 程式人生 > >演算法——最短路徑——Dijkstra演算法

演算法——最短路徑——Dijkstra演算法

下學期開學大三,是到了該考慮前程的時候了。感覺自己大一大二演算法基礎沒打好,acm也沒參加,成績也不高,唉       所以大三努力吧,接下來就是多看演算法,多寫部落格

每天一個演算法   第一個   Dijkstra演算法

Dijkstra演算法是一個求最短路徑的演算法

作用:求圖中一點到圖的其他所有點的最短路徑,要求路徑全為正的,不能有負值

時間複雜度:O(V^2)

空間複雜度:O(V)

所屬演算法類別:貪心演算法

簡單描述原理:將V(就是已經給出的圖的所有點)分成兩部分,S:已經求出最短路徑的點的集合,T=V-S:尚未求出最短路徑的點的集合,我們所要做的就是將T中的點按照距離遞增的次序加到S中,並將最短距離記錄到D中

具體步驟:

1.初始化S,T:任意取一個點加入到S中,這時S中只有這一個點,其餘點在T中

2.初始化D:對於S中的那一個點來說,如果T中的點有到該點的弧(直接路徑),則D[i]為弧值,否則則D[i]為無窮

3 從T中抽取從目前的D來看距離v0最短的一個點加入到S中

4更新D

5重複3 4直到S=V

程式碼實現:

#include<stdio.h>
#include<stdlib.h>
#define MAXVER 100
void Dijstra(int n,int v0);
int A[MAXVER][MAXVER];//鄰接矩陣 
int dist[MAXVER];//儲存最短路徑的距離的陣列 
int path[MAXVER];// path[i]為前驅頂點下標,prev[i]的值是"頂點vs"到"頂點i"的最短路徑所經歷的全部頂點中,
//位於"頂點i"之前的那個頂點。
bool final[MAXVER];//final[i]=true,表示已求得頂點i的最短路徑  
int main(){
	int n;
	//接收資料 
	printf("輸入行數\n");
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		printf("第%d行\n",i);
		for(int j=0;j<n;j++){
			scanf("%d",&A[i][j]);
		}
	}
	Dijstra(n,0);
	for(int i=0;i<n;i++){
		printf("與第%d個點的最短距離是%d\n",i,dist[i]);
	}
} 
void Dijstra(int n,int v0){//演算法實現函式 
	for(int i=0;i<n;i++){//初始化dist,即步驟2 
		dist[i]=A[v0][i];
		path[i]=v0;
		final[i]=false;
	}
	dist[0]=0;
	final[0]=0;
	for(int i=0;i<n;i++){
		int minds=0x7fffffff;
		int ind=-1;
		for(int j=0;j<n;j++){//尋找目前的路徑距離中最小的一個 
			if(!final[j]&&dist[i]<minds){
				minds=dist[j];
				ind=j;
			}
		}
		final[ind]=true;
		for(int j=0;j<n;j++){//更新dist 
			if(!final[j]&&minds+A[ind][j]<dist[j]){
				dist[j]=minds+A[ind][j];
				path[j]=ind;
			}
		}
	}
}