本题属于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; }