Dijkstra算法采用的是一种贪心的策略,声明一个数组dis来保存源点到各个顶点的最短距离和一个保存已经找到了最短路径的顶点的集合:T,初始时,原点 s 的路径权重被赋为 0 (dis[s] = 0)。若对于顶点 s 存在能直接到达的边(s,m),则把dis[m]设为w(s, m),同时把所有其他(s不能直接到达的)顶点的路径长度设为无穷大。初始时,集合T只有顶点s。
然后,从dis数组选择最小值,则该值就是源点s到该值对应的顶点的最短路径,并且把该点加入到T中,OK,此时完成一个顶点,
然后,我们需要看看新加入的顶点是否可以到达其他顶点并且看看通过该顶点到达其他点的路径长度是否比源点直接到达短,如果是,那么就替换这些顶点在dis中的值。
然后,又从distance中找到最小值,重复上述动作,直到T中包含了图的所有顶点。
理解dijstra算法关键时要能够写出最短路径表。
模板题 HDU - 2544
在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗?
Input
输入包括多组数据。每组数据第一行是两个整数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条商店到赛场的路线。
Output
对于每组输入,输出一行,表示工作人员从商店走到赛场的最短时间
Sample Input
2 1
1 2 3
3 3
1 2 5
2 3 5
3 1 2
0 0
Sample Output
3
2
#include<iostream>
#include<string.h>
using namespace std;
int const M = 110;
#define inf 1000000
int distance1[M], raod[M][M];
int judge[M];
int m, n;
int Dijstra() {
memset(judge, 0, sizeof(judge));
for (int i = 1; i <= n; i++) {
distance1[i] = raod[1][i];
}
judge[1] = 1;
distance1[1] = 0;
for (int i = 1; i <= n; i++) {
int p;
int min = inf;
for (int j = 1; j <= n; j++) {
if (!judge[j] && min > distance1[j]) {
p = j;
min = distance1[j];
}
}
judge[p] = 1;
for (int j = 1; j <= n; j++) {
if (!judge[j] && distance1[j] > distance1[p] + raod[p][j]) {
distance1[j] = distance1[p] + raod[p][j];
}
}
}
return distance1[n];
}
int main() {
while (~scanf("%d%d",&n,&m),n||m) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
raod[i][j] = inf;
}
}
int a, b, c;
for (int i = 1; i <= m; i++) {
scanf("%d%d%d",&a,&b,&c);
if (c < raod[a][b])
raod[a][b] = raod[b][a] = c;
}
cout << Dijstra() << endl;
}
return 0;
}