Dijkstra算法的主要目的:
爲了解決最小路徑問題。
Dijkstra算法採用一種貪心的策略。聲明一個數組dis來保存源點到各個頂點的最短距離和一個保存已經找到了最短路徑的頂點的集合。
初始時,原點 s 的路徑權重被賦爲 0 (dis[s] = 0),所有的dis[i]都賦值爲無窮。若對於頂點 s 存在能直接到達的邊(s,m),則把dis[m]設爲w(s, m)
例如這幅圖,按照Dijkstra的算法,起始點爲v1,先將dis[1]=0,dis[2]=無窮,dis[3]=無窮,dis[4]=無窮,dis[5]=無窮,dis[6]=無窮。然後從v1出發,有v3,v6,更新dis[3]=10,dis[6]=100,dis[5]=30,然後,將v1的flag值置成1,代表已經使用過,然後尋找最小的dis[i],發現是dis[3],從3出發,可以更新dis[4]=min(無窮,dis[3]+dist[3][4])=60,同理可以更新剩餘的點,直到每一個點都已經選取過爲止。
Dijkstra算法的代碼實現:
#include <iostream>
#include <cstdio>
#define MAX 1005
using namespace std;
int n, m, s, t;
int map[MAX][MAX];
int dis[MAX];
int vis[MAX];
int MIN(int x, int y)
{
if (x < y)
return x;
else
return y;
}
void Dijkstra()
{
for (int i = 1; i <= n; i++)
dis[i] = map[s][i];
vis[s] = 1;
dis[s] = 0;
for (int i = 1; i < n; i++)
{
int min = 0x7f7f7f7f;
int pos;
for (int j = 1; j <= n; j++)
{
if (!vis[j] && dis[j] < min)
{
min = dis[j];
pos = j;
}
}
if (min == 0x7f7f7f7f)
break;
for (int j = 1; j <= n; j++)
dis[j] = MIN(dis[j], map[pos][j] + dis[pos]);
vis[pos] = 1;
}
}
int main()
{
scanf("%d %d %d %d", &n, &m, &s, &t);
memset(vis, 0, sizeof(vis));
memset(map, 0x7f7f7f7f, sizeof(map));
while (m--)
{
int x, y, w;
scanf("%d %d %d", &x, &y, &w);
map[x][y] = map[y][x] = MIN(map[x][y], w);
}
Dijkstra();
cout << dis[t] << endl;
return 0;
}