致谢
着重感谢labuladong的算法,东哥 https://labuladong.github.io/algo/
迪杰斯特拉算法
无权图
广度优先算法BFS,层序遍历,while循环相当于纵向遍历,while中内嵌的for循环进行每一层的横向遍历,所以层数depth/step在该场景下会使用到
BFS 算法框架也是
while
循环嵌套for
循环的形式,也用了一个step
变量记录for
循环执行的次数,无非就是多用了一个visited
集合记录走过的节点,防止走回头路罢了。当你每次从队列中拿出节点cur
的时候,从start
到cur
的最短权重就是step
记录的步数。
// 输入起点,进行 BFS 搜索
int BFS(Node start) {
Queue<Node> q; // 核心数据结构
Set<Node> visited; // 避免走回头路
q.offer(start); // 将起点加入队列
visited.add(start);
int step = 0; // 记录搜索的步数
while (q not empty) {
int sz = q.size();
/* 将当前队列中的所有节点向四周扩散一步 */
for (int i = 0; i < sz; i++) {
Node cur = q.poll();
printf("从 %s 到 %s 的最短距离是 %s", start, cur, step);
/* 将 cur 的相邻节点加入队列 */
for (Node x : cur.adj()) {
if (x not in visited) {
q.offer(x);
visited.add(x);
}
}
}
step++;
}
}
加权图
到了「加权图」的场景,事情就没有这么简单了,因为你不能默认每条边的「权重」都是 1 了,这个权重可以是任意正数(Dijkstra 算法要求不能存在负权重边)。
如果沿用 BFS 算法中的 step
变量记录「步数」,显然红色路径一步就可以走到终点,但是这一步的权重很大;正确的最小权重路径应该是绿色的路径,虽然需要走很多步,但是路径权重依然很小。
「加权图」中的最短路径问题,「步数」已经没有参考意义了,「路径的权重之和」才有意义,所以这个
for
循环可以被去掉。没有
for
循环,你也没办法维护depth
变量了。如果你想同时维护depth
变量,让每个节点cur
知道自己在第几层,可以想其他办法,比如新建一个State
类,记录每个节点所在的层数。
class State {
// 记录 node 节点的深度
int depth;
TreeNode node;
State(TreeNode node, int depth) {
this.depth = depth;
this.node = node;
}
}
// 输入一棵二叉树的根节点,遍历这棵二叉树所有节点
void levelTraverse(TreeNode root) {
if (root == null) return 0;
Queue<State> q = new LinkedList<>();
q.offer(new State(root, 1));
// 遍历二叉树的每一个节点
while (!q.isEmpty()) {
State cur = q.poll();
TreeNode cur_node = cur.node;
int cur_depth = cur.depth;
printf("节点 %s 在第 %s 层", cur_node, cur_depth);
// 将子节点放入队列
if (cur_node.left != null) {
q.offer(new State(cur_node.left, cur_depth + 1));
}
if (cur_node.right != null) {
q.offer(new State(cur_node.right, cur_depth + 1));
}
}
}
标准的 Dijkstra 算法会把从起点
start
到所有其他节点的最短路径都算出来。从起点start
到节点6
的最短路径权重的值就是distTo[6]
。
类似刚才二叉树的层序遍历,我们也需要用 State
类记录一些额外信息,也就是使用 distFromStart
变量记录从起点 start
到当前这个节点的距离(在有权图中表示累积权重)。
刚才说普通 BFS 算法中,根据 BFS 的逻辑和无权图的特点,第一次遇到某个节点所走的步数就是最短距离,所以用一个
visited
数组防止走回头路,每个节点只会经过一次。
加权图中的 Dijkstra 算法和无权图中的普通 BFS 算法不同,在 Dijkstra 算法中,你第一次经过某个节点时的路径权重,不见得就是最小的,所以对于同一个节点,我们可能会经过多次,而且每次的
distFromStart
可能都不一样。如下图,取distFromStart
最小的那次,不就是从起点start
到节点5
的最短路径权重了。
伪代码
伪代码也很重要,在解决邻接表与临界矩阵类问题时,只需要在对应的伪代码处放入相应的实现即可
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
// 用 State 类记录一些额外信息,也就是使用 distFromStart 变量记录从起点 start 到当前这个节点的距离
// 在 Dijkstra 算法中,你第一次经过某个节点时的路径权重,不见得就是最小的,所以对于同一个节点,我们可能会经过多次,
// 而且每次的 distFromStart 可能都不一样
class State
{
public:
// 图节点的 id
int id;
// 从 start 节点到当前节点的距离
int distFromStart;
// 构造函数,对该对象进行初始化,记录图中某个节点对应的id和累积权重
State(int id, int distFromStart) : id(id), distFromStart(distFromStart) {}
};
class MyComp
{
public:
// 将累积权重小的放在堆顶
bool operator()(State a, State b)
{
return a.distFromStart > b.distFromStart;
}
};
// 伪代码
// 返回节点 from 到节点 to 之间的边的权重
int weight(int from, int to);
// 输入节点 s 返回 s 的相邻节点
vector<int> adj(int s);
// 输入一幅图graph和一个起点 start,计算 start 到其他节点的最短距离
// graph为图对应的邻接表
vector<int> dijkstra(int start, vector<list<vector<int>>>& graph) {
// 图中节点的个数
int V = graph.size();
// 记录最短路径的权重,你可以理解为 dp table
// 定义:distTo[i] 的值就是节点 start 到达节点 i 的最短路径权重
vector<int> distTo(V, INT_MAX);// 求最小值,所以 dp table 初始化为正无穷
// base case,start 到 start 的最短距离就是 0
distTo[start] = 0;
// 优先级队列,distFromStart 较小的排在前面
priority_queue<State, vector<State>, MyComp> pq;
// 从起点 start 开始进行 BFS
pq.push(State(start, 0));
while (!pq.empty()) {
State curState = pq.top();
pq.pop();
// 当前队首节点的ID
int curNodeID = curState.id;
// 当前队首节点的距离(累积权重),从start到该节点
int curDistFromStart = curState.distFromStart;
if (curDistFromStart > distTo[curNodeID]) {
// 已经有一条更短的路径到达 curNode 节点了
continue;
}
// 将 curNode 的相邻节点装入队列
// 遍历对应的邻接表adj,将curNodeID对应的相邻节点装入队列中
for (int nextNodeID : adj(curNodeID))
{
// 看看从 curNode 达到 nextNodeID 的距离是否会更短
int distToNextNode = distTo[curNodeID] + weight(curNodeID, nextNodeID);
// 从 curNode 达到 nextNodeID 的距离更短,更新dp table,并将nextNode入队,等待下一次出队处理
if (distToNextNode < distTo[nextNodeID])
{
// 更新 dp table
distTo[nextNodeID] = distToNextNode;
// 将这个节点以及距离放入队列,等待下一次出队处理
pq.push(State(nextNodeID, distToNextNode));
}
}
}
return distTo;
}
int main() {
return 0;
}
1、没有
visited
集合记录已访问的节点,所以一个节点会被访问多次,会被多次加入队列,那会不会导致队列永远不为空,造成死循环?
算法逻辑就是在不断的最小化
distTo
数组中的元素:如果你能让到达nextNodeID
的距离更短,那就更新distTo[nextNodeID]
的值,让你入队,否则的话对不起,不让入队。因为两个节点之间的最短距离(路径权重)肯定是一个确定的值,不可能无限减小下去,所以队列一定会空,队列空了之后,
distTo
数组中记录的就是从start
到其他节点的最短距离。2、为什么用优先级队列
PriorityQueue
而不是LinkedList
实现的普通队列?为什么要按照distFromStart
的值来排序?
- Dijkstra 算法使用优先级队列,主要是为了效率上的优化,类似一种贪心算法的思路。让你觉得哪条路径更有「潜力」成为最短路径中的一部分
3、如果我只想计算起点
start
到某一个终点end
的最短路径,是否可以修改算法,提升一些效率?// 输入一幅图graph和一个起点 start,计算 start 到其他节点的最短距离 // 注意这里的参数,根据不同的题改变 int dijkstra(int start, vector<list<vector<int>>>& graph, int end) { ... while (!pq.empty()) { ... // 标准 Dijkstra 算法会算出 start 到所有其他节点的最短路径, // 你只想计算到 end 的最短路径,相当于减少计算量 if(curNodeID == end) return curDistFromStart;// 在这里加一个判断就行了,其他代码不用改 ... } // 如果运行到这里,说明从 start 无法走到 end return INT_MAX; }
完整代码
743.网络延迟时间
有
n
个网络节点,标记为1
到n
。给你一个列表
times
,表示信号经过 有向 边的传递时间。times[i] = (ui, vi, wi)
,其中ui
是源节点,vi
是目标节点,wi
是一个信号从源节点传递到目标节点的时间。现在,从某个节点
K
发出一个信号。需要多久才能使所有节点都收到信号?如果不能使所有节点收到信号,返回-1
。
#include <iostream>
#include <vector>
#include <list>
#include <queue>
using namespace std;
// 用 State 类记录一些额外信息,也就是使用 distFromStart 变量记录从起点 start 到当前这个节点的距离
// 在 Dijkstra 算法中,你第一次经过某个节点时的路径权重,不见得就是最小的,所以对于同一个节点,我们可能会经过多次,
// 而且每次的 distFromStart 可能都不一样
class State
{
public:
// 图节点的 id
int id;
// 从 start 节点到当前节点的距离
int distFromStart;
// 构造函数,对该对象进行初始化,记录图中某个节点对应的id和累积权重
State(int id, int distFromStart) : id(id), distFromStart(distFromStart) {}
};
class MyComp
{
public:
// 将累积权重小的放在堆顶
bool operator()(State a, State b)
{
return a.distFromStart > b.distFromStart;
}
};
// 输入一幅图graph和一个起点 start,计算 start 到其他节点的最短距离
// 得到distTo数组,distTo[i] 的值就是节点 start 到达节点 i 的最短路径权重
// graph为图对应的邻接表
vector<int> dijkstra(int start, vector<list<vector<int>>>& graph)
{
// 图中节点的个数
int V = graph.size();
// 记录最短路径的权重,你可以理解为 dp table
// 定义:distTo[i] 的值就是节点 start 到达节点 i 的最短路径权重
vector<int> distTo(V, INT_MAX);// 求最小值,所以 dp table 初始化为正无穷
// base case,start 到 start 的最短距离就是 0
distTo[start] = 0;
// 优先级队列,distFromStart 较小的排在前面
priority_queue<State, vector<State>, MyComp> pq;
// 从起点 start 开始进行 BFS
pq.push(State(start, 0));
while (!pq.empty()) {
State curState = pq.top();
pq.pop();
// 当前队首节点的ID
int curNodeID = curState.id;
// 当前队首节点的距离(累积权重),从start到该节点
int curDistFromStart = curState.distFromStart;
// // 标准 Dijkstra 算法会算出 start 到所有其他节点的最短路径,
// // 你只想计算到 end 的最短路径,相当于减少计算量
// vector<int> dijkstra(int start, vector<list<vector<int>>>& graph, int end)
// if(curNodeID == end) return curDistFromStart;// 在这里加一个判断就行了,其他代码不用改
if (curDistFromStart > distTo[curNodeID]) {
// 已经有一条更短的路径到达 curNode 节点了
continue;
}
// 将 curNode 的相邻节点装入队列
for (vector<int> neighbor : graph[curNodeID])
{
// 看看从 curNode 达到 nextNodeID 的距离是否会更短
// int distToNextNode = distTo[curNodeID] + weight(curNodeID, nextNodeID);
int nextNodeID = neighbor[0];
int distToNextNode = distTo[curNodeID] + neighbor[1];
// 从 curNode 达到 nextNodeID 的距离更短,更新dp table,并将nextNode入队,等待下一次出队处理
if (distToNextNode < distTo[nextNodeID])
{
// 更新 dp table
distTo[nextNodeID] = distToNextNode;
// 将这个节点以及距离放入队列,等待下一次出队处理
pq.push(State(nextNodeID, distToNextNode));
}
}
}
return distTo;
}
// 计算从节点k到其它节点的最短路径(即最少累积权重)
// main函数调用入口处 这里的参数和返回值根据题意进行修改
// 参数:edges表示带权图 n表示有n个网络节点[1..n] k表示从节点k出发到其他所有节点的最短路径
int mainProcess(vector<vector<int>>& edges, int n, int k)
{
// 节点号从1开始,所以要创建大小为 n+1 的邻接表(大小为n+1,数组从下标0开始构建,但是我们只需要用到[1..n])
// 根据题意修改邻接表的大小:(如果图的节点号从0开始创建大小为 n 的邻接表)
// [1...n]
vector<list<vector<int>>> graph(n + 1);// 邻接表初始化
// 构造图(图可以用邻接表和邻接矩阵表示,这里采用邻接表)
for(vector<int>& edge : edges)
{
int from = edge[0];
int to = edge[1];
int weight = edge[2];
// 向第from个邻接表对应的链表上添加数组元素,邻接表存储图结构,同时存储权重信息
// graph[from]对应list类型
// from -> list<(to, weight)>
graph[from].push_back(vector<int>{to, weight});
}
// 启动dijkstra算法计算节点k为起点到达其它节点的最短路径
vector<int> distTo = dijkstra(k, graph);
// 找到最长的那一条最短路径
int res = 0;
// 如果图的节点号从0开始,那么这里遍历就从0开始,从1开始就是[1..distTo.size())
for (int i = 1; i < distTo.size(); i++)
{
// 表示无法从start位置到达i节点,直接返回-1
if(distTo[i] == INT_MAX)
{
// 有节点不可达,返回 -1
return -1;
}
res = max(res, distTo[i]);
}
return res;
}
int main() {
int n = 3;
vector<vector<int>> nums{{1, 2, 5}, {1, 3, 6}, {2, 3, 1}};
int ret = mainProcess(nums, n, 1);
cout << ret << endl;
return 0;
}
1631.最小体力消耗路径
你准备参加一场远足活动。给你一个二维
rows x columns
的地图heights
,其中heights[row][col]
表示格子(row, col)
的高度。一开始你在最左上角的格子(0, 0)
,且你希望去最右下角的格子(rows-1, columns-1)
(注意下标从 0 开始编号)。你每次可以往 上,下,左,右 四个方向之一移动,你想要找到耗费 体力 最小的一条路径。一条路径耗费的 体力值 是路径上相邻格子之间 高度差绝对值 的 最大值 决定的。
请你返回从左上角走到右下角的最小 体力消耗值 。
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
// 用 State 类记录一些额外信息
// 如果是一维邻接表,就记录成id形式,标记图中节点
// 如果是二维邻接矩阵形式的题,就声明为x,y变量,标记图中对应的节点
// 在 Dijkstra 算法中,你第一次经过某个节点时的路径权重,不见得就是最小的,所以对于同一个节点,我们可能会经过多次,
// 而且每次的 distFromStart 可能都不一样
class State
{
public:
// 二维坐标 (x, y) 是图中的一个节点
int x;
int y;
// 从起点 (0, 0) 到当前位置的最小体力消耗(距离)
int distFromStart;
// 构造函数,对该对象进行初始化,记录图中某个节点对应的id和累积权重
State(int x, int y, int distFromStart) : x(x), y(y), distFromStart(distFromStart) {}
};
class MyComp
{
public:
// 将累积权重小的放在堆顶
bool operator()(State a, State b)
{
return a.distFromStart > b.distFromStart;
}
};
// 创建二维数组表示节点在矩阵中向上、下、左、右 这四个方向前进一步时坐标的变化
vector<vector<int>> dirs{{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
// 输入节点, 返回节点在邻接矩阵中的相邻节点
vector<vector<int>> adj(vector<vector<int>>& heights, int x, int y)
{
vector<vector<int>> neighbors;
int m = heights.size();
int n = heights[0].size();
// 将该节点[x][y]向上下左右四个方向移动
// 当前坐标pos加上坐标的改变值就得到不同方向前进一步后的坐标
for(vector<int>& dir : dirs)
{
int r = x + dir[0];
int c = y + dir[1];
// 先判断向不同方向前进后得到的坐标是否越界,再判断对应位置的值是否符合条件
if(r >= 0 && r < m && c >= 0 && c < n)
{
neighbors.push_back(vector<int>{r, c});
}
}
return neighbors;
}
// Dijkstra 算法,计算 (0, 0) 到 (m - 1, n - 1) 的最小体力消耗
// Dijkstra 算法这里的参数和返回值根据题意进行修改
int dijkstra(vector<vector<int>>& heights)
{
int m = heights.size();
int n = heights[0].size();
// 记录最短路径的权重,你可以理解为 dp table
// 定义:distTo[i][j]的值为从 (0, 0) 到 (i, j) 的最小体力消耗
vector<vector<int>> distTo(m, vector<int>(n, INT_MAX));// 求最小值,所以 dp table 初始化为正无穷
// base case,[start][start] 到 [start][start] 的最短距离就是 0
distTo[0][0] = 0;
// 优先级队列,distFromStart 较小的排在前面
priority_queue<State, vector<State>, MyComp> pq;
// 从起点 start 开始进行 BFS
pq.push(State(0, 0, 0));
while (!pq.empty()) {
State curState = pq.top();
pq.pop();
// 当前队首节点的在图中的位置
int curX = curState.x;
int curY = curState.y;
// 当前队首节点的距离(累积权重),从[start][start]到该节点
int curDistFromStart = curState.distFromStart;
// // 标准 Dijkstra 算法会算出 start 到所有其他节点的最短路径,
// // 你只想计算到 end 的最短路径,相当于减少计算量
if(curX == m - 1 && curY == n - 1) return curDistFromStart;// 在这里加一个判断就行了,其他代码不用改
if (curDistFromStart > distTo[curX][curY]) {
// 已经有一条更短的路径到达 [curX][curY] 节点了
continue;
}
// 将 [curX][curY] 节点 的相邻节点装入队列
for (vector<int>& neighbor : adj(heights, curX, curY))
{
// 看看从 curNode 达到 nextNodeID 的距离 是否 会更短
// int distToNextNode = distTo[curNodeID] + weight(curNodeID, nextNodeID);
int nextNodeX = neighbor[0];
int nextNodeY = neighbor[1];
// 根据题意计算从 (curX, curY) 达到 (nextX, nextY) 的消耗
int distToNextNode = max(distTo[curX][curY], abs(heights[nextNodeX][nextNodeY] - heights[curX][curY]));
// 从 curNode 达到 nextNodeID 的距离更短,更新dp table,并将nextNode入队,等待下一次出队处理
if (distToNextNode < distTo[nextNodeX][nextNodeY])
{
// 更新 dp table
distTo[nextNodeX][nextNodeY] = distToNextNode;
// 将这个节点以及距离放入队列,等待下一次出队处理
pq.push(State(nextNodeX, nextNodeY, distToNextNode));
}
}
}
// 运行到这里,说明(0, 0) 无法到 (m - 1, n - 1),返回INT_MAX,一般情况下使用不到
return INT_MAX;
}
// main函数调用入口处 这里的参数和返回值根据题意进行修改
int mainProcess(vector<vector<int>>& heights)
{
// 如果权值在矩阵里,就需要创建对应图的邻接表
// 如果直接给出邻接矩阵以及权值的定义,那么就不需要再创建邻接表
// 启动dijkstra算法计算节点k为起点到达其它节点的最短路径
int res = dijkstra(heights);
return res;
}
int main() {
// Dijkstra 算法,计算 (0, 0) 到 (m - 1, n - 1) 的最小体力消耗
vector<vector<int>> nums{{1,2,2}, {3,8,2}, {5,3,5}};
int ret = mainProcess(nums);
cout << ret << endl;
return 0;
}
未知.星球之间的最少消耗
存在N个星球(编号从1到N),每两个星球之间有连通门,从X星球到Y星球需要通过连通门,并且需要消耗一定的能量
求连通所有星球所需要的最少能量消耗,如果无法连通所有星球,输出-1
- 最小生成树,待补充
求从星球1到达星球N所耗费的最少能量,如果无法到达星球N,输出-1
// 其中 nums[i] =[Xi,Yi,Mi] 表示星球Xi和星球Yi之间可以开启一个星际门,并消耗 Mi 能量。 vector<vector<int>> nums{{1, 2, 5}, {1, 3, 6}, {2, 3, 1}};
求从星球1到达星球N所耗费最少能量所在的路径
#include <iostream>
#include <vector>
#include <list>
#include <queue>
using namespace std;
// 用 State 类记录一些额外信息,也就是使用 distFromStart 变量记录从起点 start 到当前这个节点的距离
// 在 Dijkstra 算法中,你第一次经过某个节点时的路径权重,不见得就是最小的,所以对于同一个节点,我们可能会经过多次,
// 而且每次的 distFromStart 可能都不一样
class State
{
public:
// 图节点的 id
int id;
// 从 start 节点到当前节点的距离
int distFromStart;
// 构造函数,对该对象进行初始化,记录图中某个节点对应的id和累积权重
State(int id, int distFromStart) : id(id), distFromStart(distFromStart) {}
};
class MyComp
{
public:
// 将累积权重小的放在堆顶
bool operator()(State a, State b)
{
return a.distFromStart > b.distFromStart;
}
};
// 输入一幅图graph和一个起点 start,计算 start 到其他节点的最短距离
// 得到distTo数组,distTo[i] 的值就是节点 start 到达节点 i 的最短路径权重
// graph为图对应的邻接表
vector<int> dijkstra(int start, vector<list<vector<int>>>& graph)
{
// 图中节点的个数
int V = graph.size();
// 记录最短路径的权重,你可以理解为 dp table
// 定义:distTo[i] 的值就是节点 start 到达节点 i 的最短路径权重
vector<int> distTo(V, INT_MAX);// 求最小值,所以 dp table 初始化为正无穷
// base case,start 到 start 的最短距离就是 0
distTo[start] = 0;
// 优先级队列,distFromStart 较小的排在前面
priority_queue<State, vector<State>, MyComp> pq;
// 从起点 start 开始进行 BFS
pq.push(State(start, 0));
while (!pq.empty()) {
State curState = pq.top();
pq.pop();
// 当前队首节点的ID
int curNodeID = curState.id;
// 当前队首节点的距离(累积权重),从start到该节点
int curDistFromStart = curState.distFromStart;
// // 标准 Dijkstra 算法会算出 start 到所有其他节点的最短路径,
// // 你只想计算到 end 的最短路径,相当于减少计算量
// vector<int> dijkstra(int start, vector<list<vector<int>>>& graph, int end)
// if(curNodeID == end) return curDistFromStart;// 在这里加一个判断就行了,其他代码不用改
if (curDistFromStart > distTo[curNodeID]) {
// 已经有一条更短的路径到达 curNode 节点了
continue;
}
// 将 curNode 的相邻节点装入队列
for (vector<int> neighbor : graph[curNodeID])
{
// 看看从 curNode 达到 nextNodeID 的距离是否会更短
// int distToNextNode = distTo[curNodeID] + weight(curNodeID, nextNodeID);
int nextNodeID = neighbor[0];
int distToNextNode = distTo[curNodeID] + neighbor[1];
// 从 curNode 达到 nextNodeID 的距离更短,更新dp table,并将nextNode入队,等待下一次出队处理
if (distToNextNode < distTo[nextNodeID])
{
// 更新 dp table
distTo[nextNodeID] = distToNextNode;
// 将这个节点以及距离放入队列,等待下一次出队处理
pq.push(State(nextNodeID, distToNextNode));
}
}
}
return distTo;
}
// 计算从节点k到其它节点的最短路径(即最少累积权重)
// main函数调用入口处 这里的参数和返回值根据题意进行修改
// 参数:edges表示带权图 n表示有n个网络节点[1..n] k表示从节点k出发到其他所有节点的最短路径
int mainProcess(vector<vector<int>>& edges, int n, int k)
{
// 节点号从1开始,所以要创建大小为 n+1 的邻接表(大小为n+1,数组从下标0开始构建,但是我们只需要用到[1..n])
// 根据题意修改邻接表的大小:(如果图的节点号从0开始创建大小为 n 的邻接表)
// [1...n]
vector<list<vector<int>>> graph(n + 1);// 邻接表初始化
// 构造图(图可以用邻接表和邻接矩阵表示,这里采用邻接表)
for(vector<int>& edge : edges)
{
int from = edge[0];
int to = edge[1];
int weight = edge[2];
// 向第from个邻接表对应的链表上添加数组元素,邻接表存储图结构,同时存储权重信息
// graph[from]对应list类型
// from -> list<(to, weight)>
graph[from].push_back(vector<int>{to, weight});
}
// 启动dijkstra算法计算节点k为起点到达其它节点的最短路径
vector<int> distTo = dijkstra(k, graph);
// 找到最长的那一条最短路径
int res = 0;
// 如果图的节点号从0开始,那么这里遍历就从0开始,从1开始就是[1..distTo.size())
for (int i = 1; i < distTo.size(); i++)
{
// 表示无法从start位置到达i节点,直接返回-1
if(distTo[i] == INT_MAX)
{
// 有节点不可达,返回 -1
return -1;
}
res = max(res, distTo[i]);
}
return res;
}
int main() {
vector<vector<int>> nums{{1, 2, 1}, {1, 3, 1}, {2, 3, 3}};
// 图中星球个数
int n = 3;
int ret = mainProcess(nums, n, 1);
cout << ret << endl;
return 0;
}