#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int inf = 0x3f3f3f3f;
int d[1005];
int w[1005][1005];//存储地图,存储连通关系
int vis[1005];
int n, m;
void dij(int x)
{
for (int i = 1; i <= n; i++)
d[i] = inf;
memset(vis, 0, sizeof(vis));
d[x] = 0;
for (int i = 1; i <= n; i++)
{
int min = inf;
int k = 0;
for (int j = 1; j <= n; j++)
{
if (!vis[j] && d[j] < min)
{
k = j;
min = d[j];//寻找最短的距离
}
}
vis[k] = 1;
for (int j = 1; j <= n; j++)
{
if (!vis[j] && min + w[k][j] < d[j])
d[j] = min+w[k][j];
}
}
}
int main()
{
while (cin>>n>>m)
{
if (n == 0 && m == 0)
break;
for (int i = 1; i <= n; i++)
{
w[i][i] = inf;//相同两点之间的距离定位无穷大
for (int j = i+1; j <=n; j++)//遍历一遍
{
w[i][j] = w[j][i] = inf;//注意算法的初始化
}
}
for (int i = 0; i < m; i++)
{
int a, b, dis;
cin >> a >> b >> dis;//输入图之间的关系
w[a][b] = w[b][a] = dis;
}
dij(1);
printf("%d\n", d[n]);
}
}
1、理解迪杰斯特拉算法,有几个关键地方,首先,对于无连通关系的点,之间的距离定为无穷大,进行图的连通时,注意两边的距离的记录,其次,注意理解d[n]数组的含义,代表从起点到当前顶点的最短距离
2、只有存在连通关系的点才能够被更新,更新之后便于第二次循环时找到该点,其他未被更新的点仍处于无穷大的状态,所以利用不断更新的办法,依次进行寻找行进的顶点,在此处注意引入vis数组,用于记录该顶点是否已经被访问,所以每次在寻找最小值时,总能保证找出的最小值为起点到当前顶点的最短距离,类似于dp思想,每次进行更新直到更新至起点到终点的最短距离
int dijkstra(int n)
{
//初始化v[0]到v[i]的距离
for(int i=1;i<=n;i++)
dis[i] = w[0][i];
vis[0]=1;//标记v[0]点
for(int i = 1; i <= n; i++)
{
//查找最近点
int min = INF,k = 0;
for(int j = 0; j <= n; j++)
if(!vis[w] && dis[j] < min)
min = dis[w],k = j;
vis[k] = 1;//标记查找到的最近点
//判断是直接v[0]连接v[j]短,还是经过v[k]连接v[j]更短
for(int j = 1; j <= n; j++)
if(!vis[j] && min+w[k][j] < dis[j])
d[j] = min+w[k][j];
}
return dis[j];
}
以上为迪杰斯特拉算法实现的模板