本题属于Dijkstra算法的模板题。只需要之前迪杰斯特拉算法求出起点s到每个点的最短距离。然后输出s到t的最短距离即可。
这里简要说一下迪杰斯特拉算法的原理:
迪杰斯特拉算法使用一个贪心的思想,在每一次的路径里面最短的那一个一定是确定的,也就是说不会被其他的路径影响从而边的更短。那么我们就每次从这个最短的点出发去遍历这个点相邻的其他点。获得更短的更新以后就将其加入到优先队列里面,当然这个最短点的任务完成之后就从优先队列里面出来了。那么重复这个过程就可以求出某一个起点到所有点的最短距离了。
//dijkstra
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 1000+10;
const int maxnn = 20000+10;
//链式前向星结构体
struct sy{
int to;
int next;
int w;
} edge[maxnn];
//节点结构体
struct Node{
int number;
int c;
bool operator < (const Node &n)const {
return c>n.c;
}
};
int ans[maxn];
int head[maxn];
priority_queue<Node> pq;
map<int, int> vis;
int n, m, s, t, cnt = 0;
//链式前向星加边。
void add_edge(int x, int y, int val)
{
edge[++cnt].next = head[x];
edge[cnt].to = y;
edge[cnt].w = val;
head[x] = cnt;
}
//开始计算以s点为起点到t点的最短路径
void dijkstra()
{
//最初将最短路径全部都设为极大
memset(ans, 127, sizeof(ans));
ans[s] = 0;
//将起点设置成0
pq.push({s, 0});
while (pq.size())
{
int number = pq.top().number;
pq.pop();
//如果已经作为以及确定的最短边被访问过,那么不就不能再次访问
//毕竟再次访问的话很有可能是
if (vis[number]) continue;
vis[number] = 1;
// cout<<"number="<<number<<endl;
//遍历他所有的连边
for (int i=head[number];i;i = edge[i].next)
{
int next = edge[i].to;
int w = edge[i].w;
if (vis[next]) continue;
// cout<<"nt="<<next<<endl;
if (ans[number]+w<ans[next])
{
// cout<<"next="<<next<<endl;1
ans[next] = ans[number]+w;
pq.push({next, ans[next]});
}
}
}
if (ans[t]>INT_MAX)
{
cout<<-1;
}
else {
cout<<ans[t];
}
}
signed main()
{
int x, y ,val;
cin>>n>>m>>s>>t;
for (int i=1;i<=m;i++)
{
cin>>x>>y>>val;
add_edge(x, y, val);
add_edge(y, x, val);
}
dijkstra();
return 0;
}

京公网安备 11010502036488号