Dijkstra算法攻略

#include<iostream>
#include<algorithm>
#include<cstring>
#define Inf 0x3f3f3f3f
using namespace std;
int map[1005][1005]; //计算边权
int vis[1005], dis[1005]; //vis[i]确定是否已经是最短距离,若是每次循环都不管。 dis[i]以i为结尾的最短距离
int n, m;//n个点,m条边
void Init() //原地到原地边权为0
{
	memset(map, Inf, sizeof(map));
	for (int i = 1; i <= n; i++)
	{
		map[i][i] = 0;
	}
}
void Getmap() //输入数据
{
	int u, v, w;
	for (int t = 1; t <= m; t++)
	{
		cin >> u >> v >> w;
		if (map[u][v] > w)
		{
			map[u][v] = w;
			map[v][u] = w;
		}
	}
}
void Dijkstra(int u) //算法
{
	memset(vis, 0, sizeof(vis)); //全部为0,都没有确定
	for (int t = 1; t <= n; t++) 
	{
		dis[t] = map[u][t]; //第一轮确定以u为起点的所有dis[i]的距离,但都不是最终答案
	}
	vis[u] = 1; //确定u开始u结尾为最终答案,dis[u]实际等于0
	for (int t = 1; t < n; t++) //大循环是每次只会使一个dis成功确定
	{
		int minn = Inf, temp; //minn为每次的起点后确定的最小值,temp记录下标位置
		for (int i = 1; i <= n; i++) //计算最小值
		{
			if (!vis[i] && dis[i] < minn) //!vis判断是否确定
			{
				minn = dis[i];
				temp = i;
			}
		}
		vis[temp] = 1; //本次大循环中确定了一个以temp为下标的最小值,vis使其确定下来
		for (int i = 1; i <= n; i++) //已经确认dis[temp]为最小值,以此为起点重置相关所有点dis值
		{
			if (map[temp][i] + dis[temp] < dis[i])
			{
				dis[i] = map[temp][i] + dis[temp];
			}
		}
	}
}
int main()
{
	cin >> m >> n;
	Init();
	Getmap();
	Dijkstra(n);
	cout << dis[1];
	return 0;
}
发布了90 篇原创文章 · 获赞 15 · 访问量 3150

猜你喜欢

转载自blog.csdn.net/qq_43656233/article/details/90696699