理论基础:
求有权图中起点到某一点的最短路径问题
minDist数组:记录源点到某一节点的最短路程
三部曲:
(1)找出距离源点相距最近的点。
(2)标记该点为已访问过。
(3)更新该点相连的点的mindist:距离远点的最近路程。
这里跟prim算法不一样的地方就是第一步,prim算法要找的是距离生成树最近的节点,而迪杰斯特拉算法找的是距离源点最近的节点。
卡码网-47:参加科学大会:
题目:
题目描述
小明是一位科学家,他需要参加一场重要的国际科学大会,以展示自己的最新研究成果。
小明的起点是第一个车站,终点是最后一个车站。然而,途中的各个车站之间的道路状况、交通拥堵程度以及可能的自然因素(如天气变化)等不同,这些因素都会影响每条路径的通行时间。
小明希望能选择一条花费时间最少的路线,以确保他能够尽快到达目的地。
输入描述
第一行包含两个正整数,第一个正整数 N 表示一共有 N 个公共汽车站,第二个正整数 M 表示有 M 条公路。
接下来为 M 行,每行包括三个整数,S、E 和 V,代表了从 S 车站可以单向直达 E 车站,并且需要花费 V 单位的时间。
输出描述
输出一个整数,代表小明从起点到终点所花费的最小时间。
笔记:
这是一道模板题,再将题目数据存入邻接矩阵grid后我们就可以开始使用迪杰斯特拉算法三部曲进行解题。首先是由于起始点到原点的距离为0,所以我们先将mindist[1]置为0,接下来我们遍历图中所有的点:
(1)找出距离远点最近的节点:
在第一层循环我们需要将到源点最近距离minval设置为INT_MAX,接着遍历所有的点,找出未被访问过的点以及到源点的距离小于初始值minval的,遍历完这n个点之后我们就可以得出距离远点最近的节点。
(2)将该点置为已访问:
也就是将visited数组中的值置为true即可。
(3)更新与该节点相连节点的mindist
这里我们需要注意更新的前提是三个条件:1、当前节点为未访问状态 2、当前节点与该节点相连:grid[cur][v] != INT_MAX 3、当前节点通过该节点到达源点的距离小于自身的mindist。
#include<bits/stdc++.h>
using namespace std;int main(){int n, m;cin >> n >> m;vector<vector<int>> grid(n + 1, vector<int>(n + 1, INT_MAX));vector<bool> visited(n + 1, false);vector<int> mindist(n + 1, INT_MAX);for(int i = 1; i <= m; i++){int s,e,v;cin >> s >> e >> v;grid[s][e] = v;}mindist[1] = 0;for(int i = 1; i <= n; i++){int cur;int minval = INT_MAX;for(int v = 1; v <= n; v++){if(!visited[v] && mindist[v] < minval){minval = mindist[v];cur = v;}}visited[cur] = true;for(int v = 1; v <= n; v++){if(!visited[v] && grid[cur][v] != INT_MAX && mindist[cur] + grid[cur][v] < mindist[v]){mindist[v] = mindist[cur] + grid[cur][v];}}}if(mindist[n] == INT_MAX) cout << -1 << endl;else cout << mindist[n] << endl;return 0;
}