HDU 2544

#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];
}
以上为迪杰斯特拉算法实现的模板

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页