题意整理:
题目以边的形式给出一个有向图,要求找到图中指定两个点(1,n)中的最短路径
为了便于后续操作,我们先将给出的边权数组转化为点对之间的距离,对于没有边链接的距离为INT_MAX,对于重边取得较小值。
方法一:DFS(超时)
核心思想:
首先,我们需要从起点1开始,往能够前往的点进行搜索。此处需要维持一个vis数组记录哪些点已经进行了访问,如果再次访问将不对其进行访问,因为边权都是正值,明显对一个点再次访问不会得到更好的答案。当到达点n时停止搜索,更新答案。
由于对边的访问没有特殊顺序,所有可能每次都以最差路径为开始进行遍历,时间复杂度很高,无法通过所有测试案例
核心代码:
class Solution {
public:
int ans, len;
void dfs(vector<vector<int>>& f, vector<int>& vis, int p, int d) {
if(p == len) {//找到n点
ans = min(ans,d);
return;
}
if(d >= ans) {//剪枝
return;
}
vis[p] = d;//记录
for(int i = 1; i <= len; ++i) {
if((vis[i] == -1 || vis[i] > d + f[p][i]) && f[p][i] != INT_MAX) {
//确保不访问已经不会作为答案的路线
dfs(f, vis, i, d + f[p][i]);
}
}
}
int findShortestPath(int n, int m, vector<vector<int> >& graph) {
vector<vector<int>> f(n, vector<int>(n, INT_MAX));//距离数组
len = n - 1;
ans = INT_MAX;//初始化答案为最大值
for(vector<int>& it : graph) {
f[it[0] - 1][it[1] - 1] = min(f[it[0] - 1][it[1] - 1],it[2]);//填入边权
}
vector<int> vis(n, -1);
dfs(f, vis, 0, 0);
return ans == INT_MAX ? -1 : ans;
}
};复杂度分析:
时间复杂度:。最坏的情况下,会对每个点的边都进行一次搜索,
空间复杂度:,使用了大小为
的空间记录边,大小为
的空间记录访问情况,以及最坏为
的递归栈
方法二:dijkstra算法
核心思想:
方法一之所以会超时,主要在于每次遍历点都只是基于点的编号,没有利用其他性质,可能会出现一个点遍历多次的情况,且每次都需要对大量点进行重新更新。实际上,对于点对之间的距离,有个很好的算法既dijkstra算法。
算法思路:使用一个d数组记录从源点出发到其他点的距离。
初始化 ,其他
循环n次,每次在未标记节点中,选出d值最小的节点 x ,对其打上标记,对于从x出发的所有边(x, y)进行更新,这使得每次更新只对少数点进行更新,且不会对后续点产生影响,因为每次都是选择d最小的点。
核心代码:
class Solution {
public:
int findShortestPath(int n, int m, vector<vector<int> >& graph) {
vector<vector<int>> f(n, vector<int>(n, INT_MAX));//距离数组
for(vector<int>& it : graph) {
f[it[0] - 1][it[1] - 1] = min(f[it[0] - 1][it[1] - 1],it[2]);//填入边权
}
vector<int> vis(n, 0);//记录访问情况
vector<int> d(n, INT_MAX);//记录距离
d[0] = 0;
for(int i = 0; i < n; ++i) {
//遍历n次n个点
int x = 0, p = INT_MAX;
for(int y = 0; y < n; ++y) {
if(vis[y] == 0 && d[y] < p) {
//找到最小x值
p = d[y];
x = y;
}
}
if(p == INT_MAX) {
//无法继续找到点,结束掉
break;
}
vis[x] = 1;
for(int y = 1; y < n; ++y) {
//对点进行更新
if(f[x][y] != INT_MAX) {
d[y] = min(d[y], d[x] + f[x][y]);
}
}
}
return d[n - 1] == INT_MAX ? -1 : d[n - 1];
}
};复杂度分析:
时间复杂度:,遍历了n次,每次选取最小x需要花费
时间
空间复杂度:,使用了大小为
的空间记录边,大小为
的空间记录访问情况,大小为
的空间记录距离



京公网安备 11010502036488号