题面
有一个 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;
}