最短路径(Dijkstra算法)

版权声明:本文为博主原创文章,欢迎转载。如有问题,欢迎指正。 https://blog.csdn.net/weixin_42172261/article/details/88599241

主要思想:
用一个数组存储一个确定的点到其他各个点的初始距离,并把这个点标记,然后在剩下的n-1个点中找到距离这个给定的点距离最短的点,然后把它标记后,用它当作中转点来松弛给定点到其他点的距离。一共找n-1次就可以了,因为一开始就把给定点标记了。

模板:
代码来自啊哈算法

#include <stdio.h>
int e[101][101], dis[101], book[101];
int i, j, m, n, u, v, min;
int a, b, c, inf=99999999;
int main()
{
	scanf("%d %d", &n, &m);
	for (i=1; i<=n; i++)
		for (j=1; j<=n; j++)
			if (i==j)
				e[i][j]=0;
			else
				e[i][j]=inf;
	
	for (i=1; i<=m; i++)
	{
		scanf("%d %d %d", &a, &b, &c);
		e[a][b]=c;
	}
	
	for (i=1; i<=n; i++)//这里假定源点为1号点,可根据情况更改 
		dis[i]=e[1][i];
	
	for (i=1; i<=n; i++)
		book[i]=0;
	book[1]=1;
	//在循环开始前对1到1进行了确定,所以只需要进行n-1次循环就可以 
	for (i=1; i<=n-1; i++)
	{
		min=inf;
		for (j=1; j<=n; j++)
		{
			if (book[j]==0 && dis[j]<min)
			{
				min=dis[j];
				u=j;
			}
		}
		book[u]=1;
		for (v=1; v<=n; v++)
		{
			if (dis[u]+e[u][v]<dis[v])
				dis[v]=dis[u]+e[u][v];
		}
	}
	for (i=1; i<=n; i++)
	{
		printf("%5d", dis[i]);
	}
	return 0;
} 

分析:
只适用于解决单源最短路径问题
不能解决负边权因为当扩展到一个负边时,已经更新过的两点之间的距离可能还会被修改掉,这就违背了这个算法已经更新的边为最小值的思想了。
适用于解决稠密图

猜你喜欢

转载自blog.csdn.net/weixin_42172261/article/details/88599241