输入保证至少存在1条商店到赛场的路线。
1 2 10
1 3 4
2 4 2
3 4 3
2 5 5
#include <iostream>
using namespace std;
int a[101][101];
int vis[101][101];
int d[101];
int N, M, A, B, C;
int dp(int i) {
if (i == N) return 0;
int& ans = d[i];
if (ans != -1) return d[i];
ans = 20000000;
for (int j = 1; j <= N; ++j) {
if (a[i][j] > 0 && !vis[i][j]) { //如果i->j存在一条路并且这条路没有走过的话
vis[i][j] = vis[j][i] = 1; //将这条路删除
int t = a[i][j] + dp(j); //计算每一个 i->j的路径 + j->...->N 的最短路径
if (ans > t) ans = t; //更新i->j->...->N的最短路径
}
}
return ans;
}
int main() {
freopen("1.in", "r", stdin);
while (scanf("%d%d", &N, &M) != EOF && (N != 0 || M != 0)) {
memset(a, 0, sizeof(a));
memset(vis, 0, sizeof(vis));
memset(d, -1, sizeof(d));
while (M--) {
scanf("%d%d%d", &A, &B, &C);
a[A][B] = a[B][A] = C;
}
cout << dp(1) << endl;
}
return 0;
}
#include <iostream>
#define INF 20000000;
using namespace std;
int a[101][101];
int vis[101];
int p[101]; //p[j]表示从1到j的最短路径
int N, M, A, B, C;
int dijkstra() {
vis[1] = 1; //将1加入已求结点
int min, min_index, cur = 1;
for (int i = 2; i <= N; ++i)
p[i] = a[1][i];
for (int k = 1; k <= N-1; k++) {
min = INF;
//找到未求结点中离1最近的结点
for (int i = 1; i <= N; ++i) {
if (!vis[i] && a[cur][i] != -1 && min > p[i]) {
min = p[i];
min_index = i;
}
}
vis[min_index] = 1; //将该结点加入已求结点
cur = min_index; //记录当前结点
if (cur == N) return p[N];
//以当前结点作为中介更新未求结点的最短路径
for (int i = 1; i <= N; ++i) {
if (!vis[i] && a[cur][i] != -1 && p[i] > p[cur] + a[cur][i])
p[i] = p[cur] + a[cur][i];
}
}
return p[N];
}
int main() {
//freopen("1.in", "r", stdin);
while (scanf("%d%d", &N, &M) != EOF && (N != 0 || M != 0)) {
memset(a, -1, sizeof(a));
memset(vis, 0, sizeof(vis));
for (int i = 1; i <= N; ++i) {
for (int j = 1; j <= N; ++j)
a[i][j] = INF;
a[i][i] = 0;
}
while (M--) {
scanf("%d%d%d", &A, &B, &C);
a[A][B] = a[B][A] = C;
}
cout << dijkstra() << endl;
}
return 0;
}