Dijkstra算法的核心就是把顶点集合分成两个,一个是记录已经知道距离的,另外一个剩下的,所以当知道距离的那个集合满了就代表最短路径已经找到。
不过复杂度挺高的【初学者还未清楚理解】
- 找到跟源点距离最近的点,更新其距离
- 然后将其放进已知集合,更新所有距离【松弛操作】
#include <iostream>
#include <cstdio>
#define MAXN 1000
#define MAXINF 299999999
using namespace std;
struct Grauph {
int dist[MAXN + 10], pre[MAXN + 10];
bool vis[MAXN + 10];
int A[MAXN + 10][MAXN + 10];
};
Grauph G;
int n, m;
void init(Grauph &G, int n, int m) {
for (int i = 0; i < n; i++) {
G.dist[i] = MAXINF;
G.vis[i] = 1;
G.pre[i] = i;
for (int j = 0; j <= n; j++) G.A[i][j] = MAXINF;
}
}
void Dijkstra(Grauph &G, int s, int n) {
G.dist[s] = 0;
for (int i = 0; i < n; i++) {
int k = 0;
for (int j = 1; j <= n; j++)
if (G.vis[j] && G.dist[j] < G.dist[k])k = j;
G.vis[k] = 0;
for(int j=1;j<=n;j++)
if (G.vis[j] && G.dist[k] + G.A[k][j] < G.dist[j]) {
G.dist[j] = G.dist[k] + G.A[k][j];
G.pre[j] = k;
}
}
}
void dfs(int n) {
if (G.pre[n] == n) {
printf("%d", n);
return;
}
dfs(G.pre[n]);
printf(" -> %d", n);
return;
}
int main(int argc, char** argv) {
scanf("%d %d", &n, &m);
init(G, n, m);
for (int i = 0, x, y, w; i<m; ++i) {
scanf("%d %d %d", &x, &y, &w);
if (w<G.A[x][y]) {
G.A[x][y] = w;
G.A[y][x] = w;
}
}
int s = 1;
Dijkstra(G, s, n);
printf("length(%d -> %d) : %d \n", s, n, G.dist[n]);
dfs(n);
return 0;
}
java实现
public class Dijkstra {
private static int N = 1000;
private static int[][] Graph = {
{0, 1, 5, N, N, N, N, N, N},
{1, 0, 3, 7, 5, N, N, N, N},
{5, 3, 0, N, 1, 7, N, N, N},
{N, 7, N, 0, 2, N, 3, N, N},
{N, 5, 1, 2, 0, 3, 6, 9, N},
{N, N, 7, N, 3, 0, N, 5, N},
{N, N, N, 3, 6, N, 0, 2, 7},
{N, N, N, N, 9, 5, 2, 0, 4},
{N, N, N, N, N, N, 7, 4, 0}
};
public static void main(String[] args) {
dijkstra(0, Graph);
}
public static void dijkstra(int vs, int[][] Graph) {
int NUM = Graph[0].length;
int[] prenode = new int[NUM];
int[] mindist = new int[NUM];
boolean[] find = new boolean[NUM];
int vnear = 0;
for (int i = 0; i < mindist.length; i++) {
prenode[i] = i;
mindist[i] = Graph[vs][i];
find[i] = false;
}
find[vs] = true;
for (int v = 1; v < Graph.length; v++) {
int min = N;
for (int j = 0; j < Graph.length; j++) {
if (!find[j] && mindist[j] < min) {
min = mindist[j];
vnear = j;
}
}
find[vnear] = true;
for (int k = 0; k < Graph.length; k++) {
if (!find[k] && (min + Graph[vnear][k]) < mindist[k]) {
prenode[k] = vnear;
mindist[k] = min + Graph[vnear][k];
}
}
}
for (int i = 0; i < NUM; i++) {
System.out.println("v" + vs + "...v" + prenode[i] + "->v" + i + ",s=" + mindist[i]);
}
}
}