1. 程式人生 > >Dijkstra演算法思想及程式碼

Dijkstra演算法思想及程式碼

例:求頂點到圖中任意一點的距離最小值

思想:

1.首先初始化一個點到其本身距離為0,到其它點距離為無窮,記錄距離點為e[i][j],初始化所有點;

2.然後,接著初始化頂點到其它點的距離,記為dis[i],在正式表示頂點演算法中dis[i]儲存最小距離。初始化是到某一個點i的距離,初始化方式是dis[i]=e[1][i];

3.接著,標記元素,沒訪問過的記為Q集合,用visit[i]=0表示;訪問過的記為P集合,用visit[i]=1表示;

4.預處理完畢,第一層迴圈,以i表示1...n-1,裡面的一個迴圈是找到距離i最近的點,標記已經訪問過;

5.裡面的另一層迴圈是找到剛剛找到的距離第i個頂點距離最短的點,記為u;然後找u到v最短距離;

6.如果v點未被列舉且dis[v]>dis[u]+e[u][v],那麼就更新dis[v]的值;

7.繼續遍歷,直到所有元素都被標記為visit[i]=1;
https://blog.csdn.net/qq_35644234/article/details/60870719這一篇部落格寫得特別詳細;

#include<bits/stdc++.h>
using namespace std;
int e[111][111],dis[111],visit[111];
int n,m;
const int inf=9999999;
void init1()
{
	for(int i=1;i<=n;i++)
	{//n個點;
		for(int j=1;j<=n;j++)
		{
			if(i==j)
			e[i][j]=0;//自己到自己距離設定為0
			else
			e[i][j]=inf;//其它兩點間距離為無窮;
		}
	}
}
void init2()
{
	//初始化dis陣列,1號頂點到其餘各個頂點的初始距離 
	for(int i=1;i<=n;i++)
	{
		dis[i]=e[1][i];//1號地點到其它點距離值;
	}
	//初始化visit陣列
	for(int i=1;i<=n;i++)
	{
		visit[i]=0;//預設沒遍歷過點為0
		/*
            已知最短路程的頂點集合P和未知最短路徑的頂點集合Q
            vis[i]=1表示在P集合;vis[i]=0表示在Q集合;
		*/
	}
	visit[1]=1;//起點visit[1]初始化為1
}
void dijkstra()
{
	int i,j,u,v,min;
	for(i=1;i<=n-1;i++)
	{
		//找離i號頂點最近的頂點 
		min=inf;
		for(j=1;j<=n;j++)
		{
			if(visit[j]==0&&dis[j]<min)
			{
				min=dis[j];
				u=j;
			}
		}
		visit[u]=1;//找到1號頂點與之最近的點;
		for(v=1;v<=n;v++)
		{
			if(e[u][v]<inf)
			{//e[u][v]代表u、v兩點之間距離;
				if(visit[v]==0&&dis[v]>dis[u]+e[u][v])
                    //v點沒訪問過並且頂點到其距離大於頂點到u距離加上u、v之間距離;
				dis[v]=dis[u]+e[u][v];//到哪個點的距離為dis[v];
			}
		}
	}
}
int main()
{
	int i,j,t1,t2,t3;
	cin>>n>>m;
	init1();
	//讀入邊 
	for(i=1;i<=m;i++)
	{
		cin>>t1>>t2>>t3;
		e[t1][t2]=t3;//讀入的t3是距離值;
	}
	init2(); 
	dijkstra();//進行演算法;
	for(i=1;i<=n;i++)
	{
		cout<<dis[i]<<endl;
	}
	return 0;
}