v0为源点,N为邻接矩阵的阶,edge为邻接矩阵,maxn为常量,path用来保存路径节点的前驱,D用来保存最短路径权重和。顺便说一下,严蔚敏的数据结构中的这个算法只能保存最短路径上的节点,并得不到先后顺序。
//从某个点到其余各点间的最小距离
void dijkstra(int v0, int N, int edge[][maxn], int path[], int D[]) {
for (int v = 0; v < N; v++) {
path[v] = -1;
final[v] = false;
D[v] = edge[v0][v];
}
path[v0] = v0;
D[v0] = 0;
final[v0] = true; // final[i]为 true 时,表示i在集合S(已求得最短路径的终点的集合)中
//开始主循环,每次求得v0到某个v顶点的最短路径,并加v到S中
for (int i = 1; i < N; i++) {
int v = -1; //中途点
int min = INF; //当前所知的离v0点的最近距离
for (int w = 0; w < N; w++)
if (!final[w] && D[w] < min) { //点 w 在(V - S)中
min = D[w]; // 点 w 离 v0 更近
v = w;
}
if (v == -1)
break;
final[v] = true;
for (int w = 0; w < N; w++) //更新当前最短路径及距离
if (!final[w] && D[w] > min + edge[v][w]) {
path[w] = v;//path[w]记录d[w]暂时最短路径的最后一个
//中途节点mv,表明d[w]最后一段从点v到点w
D[w] = min + edge[v][w];
}// if
}// for
}//挑战程序设计竞赛中的这个算法好像更短
下面用一个数组track倒序存储v0到end点的最短路径所经过的点,但是若路径不唯一,这个算法只能得到一个解,在路径最短的前提下,并不嫩保证得到经过节点最少的路径
int getTrack(int v0, int end, int track[], int path[]) {
track[0] = end;
int cur = 1;
int pre = end;
while (pre != -1 && pre != v0) { //若P[v][w]为true,则w是从v0到v当前求得最短路径的顶点
pre = path[pre];
track[cur++] = pre;
}
track[cur - 1] = v0;
return cur; // 从0开始,track[]倒序保存路径,返回走过点数の个数cur
}
zzuwenjie 2017-3-19 22:54:49
代码中这样一句,d[w] = min(d[w], minV + d[v][w]);小心溢出,所以不直接相连的边距离不能设置为INT_MAX
void Dijkstra(int v0, int n, int pic[][maxn], int d[]) {
for (int i = 1; i <= n; ++i) {
d[i] = pic[v0][i];
final[i] = false;
}
final[v0] = true;
d[v0] = 0;
for (int i = 1; i < n; ++i) {
int minV = INT_MAX, u = -1;
for (int w = 1; w <= n; ++w)
if (!final[w] && minV > d[w]) {
minV = d[w];
u = w;
}
if (u == -1)
break;
final[u] = true;
for (int w = 1; w <= n; ++w)
d[w] = min(d[w], minV + pic[u][w]);
}
}
求最短路上的最大值
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
int n, m;
const int maxn = 112;
int pic[maxn][maxn];
int d[maxn];
bool final[maxn];
void dijkstra(int v0, int n, int pic[][maxn], int d[]) {
for (int i= 1;i <= n; ++i) {
d[i] = pic[v0][i];
final[i] = false;
}
final[v0] = true;
for (int i = 1; i < n; ++i) {
int minV = INF, u = v0;
for (int w= 1; w <= n; ++w) {
if(!final[w] && minV > d[w]) {
minV = d[w];
u = w;
}
}
if (u == -1)
break;
final[u] = true;
for(int w = 1; w <= n; ++w)
if (!final[w])
d[w] = min(d[w], max(d[u], pic[u][w]));
}
}
int main()
{
while(~scanf("%d%d", &n, &m)) {
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= i; ++j)
pic[i][j] = pic[j][i] = (i == j ? 0 : INF);
for (int i= 0;i < m; ++i) {
int x, y, d;
scanf("%d%d%d", &x, &y, &d);
pic[x][y] = pic[y][x] = min(pic[x][y], d);
}
scanf("%d", &m);
while(m-- > 0) {
int x, y;
scanf("%d%d", &x, &y);
dijkstra(x, n, pic, d);
printf("%d\n", d[y] == INF ? -1 : d[y]);
}
}
return 0;
}