class Solution {
public:
int networkDelayTime(vector<vector<int>>& times, int n, int k) {
const int inf = INT_MAX/2; //定义无穷距离,除 2 是为了防止计算距离的时候溢出
// 标记变量 visited 数组
// 0 表示索引对应的节点未被访问过,还没有计算过从原点到对应节点的最短距离值,所以用无穷来初始化;
// 1 表示索引对应的节点正在访问中,计算了当前从原点到对应节点的最短距离值,但后面可能会被更改;
// 0,1 标记的节点称为 未确定节点
// 2 表示索引对应的节点已经访问过,计算了从原点到对应节点的最短距离值,后面不会再更改,
// 2 标记的节点被称为 确定节点
// 注意,如果是在网格中搜索,那么下面三个变量就需要定义为矩阵变量
vector<int> visited(n,0); // 标记变量
vector<int> dist(n, inf); // 距离变量,记录原点到对应节点的当前最短距离,用无穷作初始化
vector<int> parent(n); // 路径变量,记录路径中到对应节点的父节点
// 建图,同时将节点编号重新定位到 0 ~ n-1
vector<vector<int>> graph(n, vector<int>(n,inf)); // 因为是有权图,所以用邻接矩阵来记录图
for(int i=0; i<times.size(); i++)
{
graph[times[i][0]-1][times[i][1]-1] = times[i][2];
}
// Dijkstra 算法初始化
// 原点的编号为 k-1
visited[k-1] = 1; // 原点目前未正在访问中,还属于未确定节点
dist[k-1] = 0; // 计算原点到原点的距离值为 0
parent[k-1] = k-1; // 在路径中,原点没有父节点,那么就将父节点记为自己
// 开始执行 Dijkstra 算法
while(1)
{
// 在未确定节点中找到当前距离值最小的节点,并标记为当前的确定节点,线性扫描法
int minDistNode = -1;
for(int i=0; i<n; i++)
{
if(visited[i]!=2 && (minDistNode==-1 || dist[i]<dist[minDistNode]))
minDistNode = i;
}
if(minDistNode==-1) // 没有未确定的节点了,停止搜索
break;
else
visited[minDistNode] = 2; // 标记为当前的确定节点,如果是要找目的节点,就在这里判断该节点是否是目的节点,如果找到了,也停止搜索
// 计算从原点到当前的确定节点的邻节点的距离值,这里假设了任意两个节点之间都有一条边,如果实际上不存在,则边的权值为无穷
for(int i=0; i<n; i++)
{
// 只对未确定的节点进行计算
if(visited[i]!=2)
{
int curDist = dist[minDistNode] + graph[minDistNode][i]; // 计算当前距离值
if(curDist < dist[i])
{
// 找到了从原点到当前的未确定节点更短的路径
parent[i] = minDistNode; // 更改路径
dist[i] = dist[minDistNode] + graph[minDistNode][i]; // 更改距离值
}
}
}
}
// 收尾工作
int ans = *max_element(dist.begin(), dist.end());
return ans == inf ? -1 : ans;
}
};
Dijkstra算法模板 - 解决网络延迟时间问题
最新推荐文章于 2024-09-28 15:28:59 发布