洛谷 P1339 [USACO09OCT]热浪

题面

有一个 n 个点 m 条边的无向图,请求出从 s 到 t 的最短路长度

分析

简单的无向图最短路问题,采用堆优化的dijkstra
dijkstra:初始到所有点的距离标记为很大很大,两个集合:已发现和未发现。
将起点距离标记为0。
之后,每次从未发现的节点集合中挑选距离起点最近的(单源最短路)放入已发现的节点集合,并且更新其相邻节点的单源距离。
如此往复,每次更新一个节点。

堆优化了红字部分,在每次更新的时候将新加入的边放入一个小根堆,所以每次取出的都是边最小的,对于取出已经更新的边,用vis来跳过

代码

#include "cstdlib"
#include <iostream>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
#define INF 2147483647
vector<pair<int, int> >v[2505];
int d[2505];
int vis[2505];
struct HeapNode
{
	int u;
	int dis;
	HeapNode(int& v, int& di) :u(v), dis(di) {}//构造方法
	HeapNode() {}
	bool operator < (const HeapNode& rhs)const
	{
		return dis > rhs.dis;
	}
};
priority_queue<HeapNode>p;
int main()
{
	int n, m, s,t;//点的个数、有向边的个数、出发点的编号、结束点编号
	cin >> n >> m >> s>>t;
	register int f, g, w;
	for (int i = 0; i < m;i++)
	{
		cin >> f >> g >> w;
		v[f].push_back(make_pair(g, w));//无向边
		v[g].push_back(make_pair(f, w));
	}
	for (int i = 1;i <= n;i++)d[i] = INF;
	d[s] = 0;
	p.push(HeapNode(s, d[s]));//从s点开始
	register int x, temp;
	register HeapNode hn;
	while (!p.empty())//每一次,从未选的集合中,挑选dis最小的一个点加入已选集合,并更新其相邻节点
	{
		temp = INF;
		hn = p.top();p.pop();//堆保证每次取出的dis尽量小(可能有重复的元素,在continue那步跳过)
		x = hn.u;
		if (vis[x])continue;
		vis[x] = 1;
		for (int j = 0;j < v[x].size();j++)
		{
			if (v[x][j].second + d[x] < d[v[x][j].first])//更新相邻节点
			{
				d[v[x][j].first] = v[x][j].second + d[x];
				p.push(HeapNode(v[x][j].first, d[v[x][j].first]));
			}
		}
	}
	cout << d[t];
	return 0;
}
发布了32 篇原创文章 · 获赞 0 · 访问量 1175

猜你喜欢

转载自blog.csdn.net/engineoid/article/details/104284611