Dijkstra演算法1:鄰接矩陣表示
從某個源點到其餘各頂點的最短路徑問題:
Dijkstra演算法解決了有向圖G=(V,E)上帶權的單源最短路徑問題,但是要求所有邊的權值非負(原因後面敘述)。
Dijkstra演算法思想為:設 G = (V, E) 是一個帶權有向圖,把圖中頂點集合 V 分成兩組,第一組為以求出最短路徑頂點的集合(用S表
示,初始時 S 中只有一個源點,以後每求得一條最短路徑 , 就將其加入到集合 S 中,直到全部頂點都加入到 S 中,演算法就結束了)
,第二組為其餘未確定最短路徑的頂點的集合(用U表示),按最短路徑長度的遞增次序依次把第二組的頂點加入 S 中。在加入的過
程中,總保持從源點 v 到 S 中各頂點的最短路徑長度不大於從源點
v 到 U 中任何頂點的最短路徑長度。此外,每個頂點對應一個距
離,S 中的頂點的距離就是從 v 到此頂點的最短路徑長,U中的頂點的距離,是從 v 到此頂點只包括 S 中的頂點為中間頂點的當前最短
路徑長度。虛擬碼:
DIJKSTRA(G, w, s)
1 INITIALIZE-SINGLE-SOURCE(G, s)//初始源
2 S ← Ø
3 Q ← V[G]
4 while Q ≠ Ø
5 do u ← EXTRACT-MIN(Q)//找出Q中距離源最短路徑
6 S ← S ∪{u}
7 for each vertex v ∈ Adj[u]
8 do RELAX(u, v, w)//鬆弛操作
單源最短路徑演算法中使用了鬆弛(relaxation)操作。對於每個頂點v∈V,都設定一個屬性d[v],用來描述從源點s到v的最短路徑上權值的上界,稱為最短路徑估計(shortest-path estimate)。π[v]代表S到v的當前最短路徑中v點之前的一個點的編號。一次鬆弛操作可以減小最短路徑估計的值d[v]。
每個單源最短路徑演算法中都會呼叫INITIALIZE-SINGLE-SOURCE,然後重複對邊進行鬆弛的過程。另外,鬆弛是改變最短路徑和前趨的唯一方式。下面的虛擬碼對邊(u,v)進行了一步鬆弛操作。
RELAX(u, v, w)
if(d[v]>d[u]+w(u, v))
then d[v]←d[u]+w(u,v)
π[v]←u
程式例項:在每年的校賽裡,所有進入決賽的同學都會獲得一件很漂亮的t-shirt。但是每當我們的工作人員把上百件的衣服從商店運回到賽場的時候,卻是非常累的!所以現在他們想要尋找最短的從商店到賽場的路線,你可以幫助他們嗎?
輸入包括多組資料。每組資料第一行是兩個整數N、M(N<=100,M<=10000),N表示成都的大街上有幾個路口,標號為1的路口是商店所在地,標號為N的路口是賽場所在地,M則表示在成都有幾條路。N=M=0表示輸入結束。接下來M行,每行包括3個整數A,B,C(1<=A,B<=N,1<=C<=1000),表示在路口A與路口B之間有一條路,我們的工作人員需要C分鐘的時間走過這條路。
輸入保證至少存在1條商店到賽場的路線。
輸出:
對於每組輸入,輸出一行,表示工作人員從商店走到賽場的最短時間
示例:
2 1 1 2 3 3 3 1 2 5 2 3 5 3 1 2 0 0
#include<cstdio>
#include <climits>
#include <iostream>
using namespace std;
const int inf = INT_MAX>>1;
const int NV = 101;
int dis[NV];
int map1[NV][NV];
bool mark[NV];
int m,n;
void dijkstra(int src)
{
int i, k, j,minf;
for( i = 0; i < n; ++i)
{
mark[i] = false;
dis[i] = map1[src][i];
}
dis[src] = 0;
mark[src] = true;
for( i = 1; i < n; ++i)
{
minf = inf;
k = src;
for(j = 0; j < n; ++j)
{
if(dis[j] < minf && (!mark[j]))
{
minf = dis[j];
k = j;
}
}
mark[k] = true;
for(j = 0; j < n; j++)
{
int temp = dis[k] + map1[k][j];
if(!mark[j] && temp < dis[j])
dis[j] = temp;
}
}
return;
}
int main()
{
while(scanf("%d %d",&n,&m), m || n)
{
for(int i = 0; i < n; ++i)
{
map1[i][i] = inf;
for(int j = i + 1; j < n; j++)
{
map1[i][j] = inf;
map1[j][i] = inf;
}
}
while(m--)
{
int v1,v2,t;
scanf("%d %d %d", &v1, &v2, &t);
if(map1[v1 - 1][v2 - 1] > t)
{
map1[v1 - 1][v2 - 1] = t;
map1[v2 - 1][v1 - 1] = t;
}
}
dijkstra(0);
printf("%d",dis[n - 1]);
}
return 0;
}
相關推薦
Dijkstra演算法1:鄰接矩陣表示
從某個源點到其餘各頂點的最短路徑問題: Dijkstra演算法解決了有向圖G=(V,E)上帶權的單源最短路徑問題,但是要求所有邊的權值非負(原因後面敘述)。 Dijkstra演算法思想為:設 G = (V, E) 是一個帶權有向圖,把圖中頂點集合 V 分成兩組,第一組為以
圖的鄰接矩陣表示與最短路徑演算法( Dijkstra )程式碼實現
#include <stdio.h> #define MAX_VERTEX_NUM 20 //最大頂點個數 typedef int VRTYPE, InfoType; typedef enum {DG, DN, UDG, UD
最短路徑(二)—Dijkstra演算法(通過邊實現鬆弛:鄰接矩陣)
上一節通過Floyd-Warshall演算法寫了多源節點最短路徑問題: 這一節來學習指定一個點(源點)到其餘各個頂點的最短路徑。也叫做“單源最短路徑”Dijkstra。 例如求下圖中1號頂點到2、3、4、5、6號頂點的最短路徑。 用二維陣列e儲存頂點之間邊的關係,初
Dijkstra演算法-最短路徑-鄰接矩陣表示
圖結構練習——最短路徑 Time Limit: 1000MS Memory Limit: 65536KB Problem Description 給定一個帶權無向圖,求節點1到節點n的最短路徑。 Input 輸入包含多組資料,格式如下。 第一行包括兩
圖相關(三)圖的鄰接矩陣表示(C++)及最最小生成樹演算法(prim和kruskal)
一.測試用圖 鄰接矩陣表示: //prim注意是無向圖 vector<vector<int>> p(6, vector<int>(6, INF));//類似dijikstra,沒有邊的點設為INF p[0][1] = 10;
圖相關(二)圖的鄰接矩陣表示(C++)及最短路徑演算法
一.Dijikstra演算法 注意:計算最短路徑時,需要把鄰接矩陣中沒有邊的位置初始化為無窮大;此處以INF表示,INF可以取0x3f3f3f3f,不能直接設為INT_MAX(因為做加法時會上溢)。 測試用圖: 其鄰接矩陣表示為: vector<vector<int
資料結構 圖的鄰接表表示轉換成鄰接矩陣表示的演算法
圖的鄰接表表示轉換成鄰接矩陣表示的演算法。 下面這個是有向圖鄰接表表示轉換成鄰接矩陣 #include <stdio.h> #include <string.h> #include <stdlib.h> int a[100][100];
圖的基本概念;圖的儲存表示:鄰接矩陣、鄰接表
無向圖 邊(vi,vj) 有向圖 弧 有向完全圖和無向完全圖 有向圖最多有n(n-1)條邊,且有n(n-1)條邊的有向圖為有向完全圖。 無向圖最多有n(n-1)/2條邊,且有n(n-1)/2條邊
無向圖的表示:鄰接矩陣和鄰接表
這裡將一個無向圖用鄰接表和鄰接矩陣表示。 輸入:頂底個數n,圖中的各個邊(用兩個頂點表示)。 輸出:這個無線圖的鄰接矩陣和鄰接表,其中鄰接表中的連結按元素大小升序排列。 先給出一個例子說明。假設有無向圖如下,則其鄰接矩陣和鄰接表如提示框中所示(其實就是下面程式的輸出)。
(c++)資料結構與演算法之圖:鄰接矩陣、深度廣度遍歷、構造最小生成樹(prim、kruskal演算法)
//圖的鄰接矩陣實現 //廣度遍歷bfs和深度遍歷dfs //構造最小生成樹的prim、kruskal演算法 #include <iostream> #include<stack> #include<queue> #define WEI
鄰接矩陣表示圖
兩種 http down leetcode img mas gen eat cnblogs 圖常用兩種方式表示,鄰接矩陣、鄰接表。 0、結構初始化 struct GraphNode { int Nv; /* 頂點數 */ int
每週一演算法(1):漢諾塔
首先漢諾塔是使用遞迴一個非常經典的例子, 歷史故事說了也沒用,我們想象原理。 前提,三根柱子ABC,將A上的盤子數按順序挪到C,每次只能一個 1. 一個盤子,A->C 2. 兩個盤子 A->B, A->C, B->C 3. 大於兩個盤子,那
1-7 鄰接矩陣儲存圖的深度優先遍歷 (10 分)
試實現鄰接矩陣儲存圖的深度優先遍歷。 函式介面定義: void DFS( MGraph Graph, Vertex V, void (*Visit)(Vertex) ); 其中MGraph是鄰接矩陣儲存的圖,定義如下: typedef struct GNode *PtrToGNod
Dijkstra演算法1.1(模板)
輸入給了你一個n個節點的無向圖的鄰接矩陣的下三角部分.要求你輸出從第0個點到所有其他點的距離的最大值 #include<cstdio> #include<cstring> #include<vector> #include<queu
C++ 圖的鄰接矩陣表示以及深度優先和廣度優先遍歷
Node.h 宣告頂點類 #pragma once class Node { public: Node(char data=0); char m_cData; bool m_bIsVisited; }; Node.cpp 實現頂點的成員以及操作函式 #incl
圖相關(一)圖的鄰接矩陣表示(C++)及圖的遍歷
一.圖的鄰接矩陣表示法 struct graph { vector<vector<int>> cost;//鄰接矩陣 vector<string> vertex;//頂點的值,用string較好,節點的名字可以是v1,v
LeetCode演算法1:java 兩數之和
問題: 給定一個整數陣列 nums 和一個目標值 target,請你在該陣列中找出和為目標值的那 兩個 整數,並返回他們的陣列下標。 你可以假設每種輸入只會對應一個答案。但是,你不能重複利用這個陣列中同樣的元素。 示例: 給定 nums = [2, 7, 11, 15],
演算法概念:大O表示法/小o表示法/Ω/Θ
對於任何數學函式,這三個記號可以用來度量其“漸近表現”,即當趨於無窮大時的階的情況,這是演算法分析中非常重要的概念。大家可以把它們分別想象成≤、≥和,分別估計了函式的漸近上界、漸近下界和準確界。誠然,漸近關係和確切大小關係是有區別的,但當問題規模很大時,忽略這種區別能大大降低演算法分析的難度。 下面我
判斷無向圖圖的連通性,鄰接矩陣表示
在古老的魔獸傳說中,有兩個軍團,一個叫天災,一個叫近衛。在他們所在的地域,有n個隘口,編號為1..n,某些隘口之間是有通道連線的。其中近衛軍團在1號隘口,天災軍團在n號隘口。某一天,天災軍團的領袖巫妖王決定派兵攻打近衛軍團,天災軍團的部隊如此龐大,甚至可以填江過河。但是巫妖王不想付出不必要的代價,他想知道
圖 | 儲存結構:鄰接矩陣及C語言實現
使用圖結構表示的資料元素之間雖然具有“多對多”的關係,但是同樣可以採用順序儲存,也就是使用陣列有效地儲存圖。 鄰接矩陣 鄰接矩陣(Adjacency Matrix),又稱 陣列表示法,儲存方式是用兩個陣列來表示圖: 一個一維陣列儲存圖中頂點本身資訊