1. 程式人生 > >Dijkstra演算法(單元點最短路徑)

Dijkstra演算法(單元點最短路徑)

Dijkstra演算法解決圖中某特定點到其他點的最短路徑。

迪傑斯塔拉(Dijkstra)演算法思想:

按路徑長度遞增的次序產生最短路徑的演算法。設集合S存放已經找到最短路徑的頂點,V為所有節點的集合,S的初始狀態只包含源點V0,對Vi∈V-S。

假設從源點V0到Vi的有向邊為最短路徑,以後每求得一條最短路V0……Vk,就把Vk加入集合S裡,並將路徑V0……Vk,Vi與原來的假設比較,取路徑較短者為最短路徑。

重複上述過程,直到集合V中全部頂點加入集合S裡。演算法結束。

理解:

①對於集合S和集合V-S,每次迭代都把集合V-S中與源點V0距離最小的點Vk加入集合S

②然後重新計算集合V-S中所有點與V0的最短距離

③如果所有點都已經加入S則結束,否則繼續從①開始

/*************************************************************************
    > File Name: Dijkstra.cpp
    > Author: Shorey
    > Mail: [email protected]
    > Created Time: 2015年04月24日 星期五 17時12分25秒
 ************************************************************************/

#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<stack>
#define M 100
#define N 100
#define INT_MAX 10000
using namespace std;
typedef struct node
{
	int matrix[N][M];
	int n;
	int e;
}MGraph;

void DijkstraPath(MGraph g, int *dist, int *path, int v0)//v0表示源頂點
{
	bool *visited = new bool[g.n];
	for(int i=0; i<g.n; i++)              //初始化工作
	{
		if(g.matrix[v0][i]>0 && i!=v0)
		{
			dist[i] = g.matrix[v0][i];
			path[i] = v0;
		}
		else
		{
			dist[i] = INT_MAX;           //若i不與v0直接相鄰,則權值為無窮大
			path[i] = -1;
		}
		visited[i] = false;
		path[v0] = v0;
		dist[v0] = 0;
	}
	visited[v0] = true;     //v0設為已經訪問

	for(int i=1; i<g.n; i++) //迴圈n-1次,尋找把剩餘結點加入的路徑
	{
		int min = INT_MAX;
		int u;
		for(int j=0; j<g.n; j++)//尋找未被擴充套件的權值最小的頂點
		{
			if(visited[j]==false && dist[j]<min)
			{
				min = dist[j];
				u = j;
			}
		}
		visited[u] = true;//把上步找到的結點加入路徑中
		for(int k=0; k<g.n; k++)//更新dist陣列的值和路徑的值
		{
			if(visited[k]==false && g.matrix[u][k]>0 && min+g.matrix[u][k]<dist[k])
			{
				dist[k] = min+g.matrix[u][k];
				path[k] = u;
			}
		}
	}
}

void showPath(int *path, int v, int v0)
{
	stack<int> s;
	int u = v;
	while(v!=v0)
	{
		s.push(v);
		v = path[v];
	}
	s.push(v);
	while(!s.empty())
	{
		printf("%d ",s.top());
		s.pop();
	}
}
int main()
{
	int n,e;
	while(scanf("%d%d",&n,&e) && e!=0)
	{
		MGraph g;
		int v0;
		int *dist = new int[n];
		int *path = new int[n];
		for(int i=0; i<N; i++)
			for(int j=0; j<M; j++)
				g.matrix[i][j] = 0;
		g.n = n;
		g.e = e;
		for(int i=0; i<e; i++)
		{
			int s,t,w;
			scanf("%d%d%d",&s,&t,&w);
			g.matrix[s][t] = w;
		}
		scanf("%d",&v0);
		DijkstraPath(g, dist, path, v0);
		for(int i=0; i<n; i++)
		{
			if(i!=v0)
			{
				showPath(path, i, v0);
				printf("%d\n",dist[i]);
			}
		}
	}
	return 0;
}


相關推薦

Dijkstra演算法單元路徑

Dijkstra演算法解決圖中某特定點到其他點的最短路徑。 迪傑斯塔拉(Dijkstra)演算法思想: 按路徑長度遞增的次序產生最短路徑的演算法。設集合S存放已經找到最短路徑的頂點,V為所有節點的集合,S的初始狀態只包含源點V0,對Vi∈V-S。 假設從源點V0到Vi的有向

貪心演算法--Dijkstra演算法單源路徑演算法

其實網上有很多寫Dijkstra演算法的前輩們,我只是分享一下我自己寫的一點心得,還有希望前輩來可以知道自己的錯誤。其實自己在寫的過程中,發現你寫一個演算法,關鍵看您對於它瞭解有多少?你的理解是透徹清楚的嗎?還有自己得認真去回味它一步一步是如何得到的,又是怎樣的過程,問題就

迪傑斯特拉演算法可列印路徑資料結構題集C語言版7.11

轉自 https://blog.csdn.net/cxllyg/article/details/7604812   #include <iostream> #include <iomanip> #include <string> usi

圖的基本演算法單源路徑

在許多路由問題中,尋找圖中一個頂點到另一個頂點的最短路徑或最小帶權路徑是非常重要的提煉過程。正式表述為,給定一個帶權有向圖G = (V, E) , 頂點s到v中頂點t的最短路徑為在邊集E中連線s到t代價

使用鄰接矩陣+Dijkstra演算法求解單源路徑問題

Dijkstra演算法是求解有向帶權圖中某一結點到其它結點的最短路徑演算法。這個演算法和Prim演算法求解最小生成樹有點相似,它也是先有一個初始頂點,然後查詢最小帶權路徑。 不同的是,Prim需要更新最小生成樹的結點,不斷將結點更新到VT中,然後更新low_cost[]陣列

迪傑斯特拉(Dijkstra)演算法求圖中路徑

迪傑斯特拉(Dijkstra )演算法: 對於圖G=(V,E),將圖的頂點分為兩組: 頂點集S:已求出的最短路徑的頂點集合(初始為{v0}); 頂點集V-S:尚未求出最短路徑的頂點集合(初始為V-{v0} )。 演算法按最短路徑長度的遞增順序逐個將

dijkstra演算法求單源路徑長度並輸出路徑 程式碼

程式碼 /* 6 8 0 0 1 1 0 3 4 0 4 4 1 3 2 2 5 1 3 2 2 3 4 3 4 5 3 */ #include<iostream> #include&l

Dijkstra演算法詳細(單源路徑演算法)

介紹 對於dijkstra演算法,很多人可能感覺熟悉而又陌生,可能大部分人比較瞭解bfs和dfs,而對dijkstra和floyd演算法可能知道大概是圖論中的某個演算法,但是可能不清楚其中的作用和原理,又或許,你曾經感覺它很難,那麼,這個時候正適合你重新認識它。 Dijkstra能是幹啥的? Dijks

POJ-3268 牛的來回長時間單源路徑

題目大意: 有編號為1-N的牛,它們之間存在一些單向的路徑。給定一頭牛的編號,其他牛要去拜訪它並且拜訪完之後要返回自己原來的位置,求這些牛中所花的最長的來回時間是多少。 給出N頭牛,M條路,要拜訪牛的編號X。 思路: 也就是每頭牛都要已最短路徑到達X號牛,並且從X號牛

POJ3268 牛的長來回時間單源路徑

有編號為1-N的牛,它們之間存在一些單向的路徑。給定一頭牛的編號,其他牛要去拜訪它並且拜訪完之後要返回自己原來的位置,求這些牛中所花的最長的來回時間是多少。 每頭牛返回的最短時間很簡單就可以算出來,這相當於從目標牛為起點求單源最短路徑。但每頭牛出發到目標牛的最短時間無法直接

資料結構::迷宮--棧的一個應用求迷宮路徑

      上篇文章我們知道求解迷宮通路的方法,但是一個迷宮有時是不止一條出路,在這些出路中,我們如何找到最短的那一條,這就是我今天要說的迷宮最短路徑問題。 (此處使用的圖): 【先來分析有什麼解決方案:】 1、方法一:我們如果採用上章中遞迴的方式,將所走的路用2標記起來

一個例子讓你明白一個演算法-Dijkstra求源到各頂點路徑

演算法思想 1.在一個圖中,把所有頂點分為兩個集合P,Q(P為最短路徑集合,Q為待選集合),用dis陣列儲存源點到各個頂點的最短路徑(到自身為0)。 2.初始化P集合,就是加入源點到該集合,並在ma

Dijkstra [迪傑斯特拉]演算法思路求單到其他每個的各個路徑Floyd演算法:任意兩點間短距離

先給出一個無向圖 用Dijkstra演算法(迪傑斯特拉演算法)找出以A為起點的單源最短路徑步驟如下 應用Dijkstra演算法計算從源頂點1到其它頂點間最短路徑的過程列在下表中。 Dijkstra演算法的迭代過程: Floyd演算法思想: 1、從任意一條單邊路徑開

Dijkstra從一個源到其他各路徑

#include <stdio.h> #include <stdlib.h> #define MAXSIZE 100 typedef struct { int vertex[MAXSIZE]; int edges[MAXSIZE][MAXSIZE]; }Gra

圖解-迪傑斯特拉演算法路徑Dijkstra's Algorithm (finding shortestpaths)

轉自:http://www.mathcs.emory.edu/~cheung/Courses/171/Syllabus/11-Graph/dijkstra2.html   一. 圖解迪傑斯特拉   Before showing you the&nb

迪傑斯特拉Dijkstra演算法--有向網路路徑

單源最短路徑問題是:對於給定的有向網路G=(V,E)及單個源點v,求v到G的其餘各頂點的最短路徑。 演算法的基本思想 a.初始時,S只包含源點,即S={v},v的距離為0。U包含除v外的其他頂點,即:U={其餘頂點},若v與U中頂點u有邊,則<u,v>

迪傑斯特拉Dijkstra演算法--無向網路路徑

與有向網路不同的是,無向網路的鄰接矩陣是對稱的,所以在構造鄰接矩陣的時候要注意。Dijkstra演算法的具體內容參照我上次寫的迪傑斯特拉(Dijstra)演算法——有向網路最短路徑 下面直接放程式碼和例項,以便更加理解使用。 #include<stdio.

無向圖的Dijkstra演算法求任意一對頂點間的路徑迪傑斯特拉演算法

public class Main{ public static int dijkstra(int[][] w1,int start,int end) { boolean[] isLable = new boolean[w1[0].length];//是否標上所有的號 i

Dijkstra演算法一個節點到其他所有節點的路徑

Dijkstra(迪傑斯特拉)演算法是典型的單源最短路徑演算法,用於計算一個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。Dijkstra演算法是很有代表性的最短路徑演算法,在很多專業課程中都作為基本內容有詳細的介紹,如資料

單源路徑演算法Dijkstra演算法

背景知識 圖簡介 圖由節點和邊組成,邊有方向的圖稱為有向圖,邊沒有方向的圖稱為無向圖,最短路徑演算法裡可以把無向圖視為雙向連線的有向圖。 邊有權重的圖稱為有權圖,邊沒有權重的圖稱為無權圖,無權圖可以視為邊的權重均為1的圖。 單源點最短路徑 給定