LeetCode 2662.前往目标的最小代价 DJ

  • https://leetcode.cn/problems/minimum-cost-of-a-path-with-special-roads/?

  • 给你一个数组 start ,其中 start = [startX, startY] 表示你的初始位置位于二维空间上的 (startX, startY) 。另给你一个数组 target ,其中 target = [targetX, targetY] 表示你的目标位置 (targetX, targetY) 。

  • 从位置 (x1, y1) 到空间中任一其他位置 (x2, y2) 的代价是 |x2 - x1| + |y2 - y1| 。

  • 给你一个二维数组 specialRoads ,表示空间中存在的一些特殊路径。其中 specialRoads[i] = [x1i, y1i, x2i, y2i, costi] 表示第 i 条特殊路径可以从 (x1i, y1i) 到 (x2i, y2i) ,但成本等于 costi 。你可以使用每条特殊路径任意次数。

  • 返回从 (startX, startY) 到 (targetX, targetY) 所需的最小代价。

示例 1:

输入:start = [1,1], target = [4,5], specialRoads = [[1,2,3,3,2],[3,4,4,5,1]]
输出:5
解释:从 (1,1)(4,5) 的最优路径如下:
- (1,1) -> (1,2) ,移动的代价是 |1 - 1| + |2 - 1| = 1- (1,2) -> (3,3) ,移动使用第一条特殊路径,代价是 2- (3,3) -> (3,4) ,移动的代价是 |3 - 3| + |4 - 3| = 1.
- (3,4) -> (4,5) ,移动使用第二条特殊路径,代价是 1 。
总代价是 1 + 2 + 1 + 1 = 5 。
可以证明无法以小于 5 的代价完成从 (1,1)(4,5) 。
示例 2:

输入:start = [3,2], target = [5,7], specialRoads = [[3,2,3,4,4],[3,3,5,5,5],[3,4,5,6,6]]
输出:7
解释:最优路径是不使用任何特殊路径,直接以 |5 - 3| + |7 - 2| = 7 的代价从初始位置到达目标位置。
  • Dijkstra
  • 类似广度优先搜索的方法解决赋权图的单源最短路径问题。(本算法每次取出未访问结点中距离最小的,用该结点更新其他结点的距离。)
  • Dijkstra 一个顶点作为源结点然后找到该顶点到图中所有其它结点的最短路径,产生一个最短路径树。
  • 注意:Dijkstra 算法不能有效处理带有负权边的图.
// 因为是完全图的题目,所以可以省略建图的过程
class Solution {
private:
    int getCost(int x1, int y1, int x2, int y2) {
        return abs(x2 - x1) + abs(y2 - y1);
    }
public:
    int minimumCost(vector& s, vector& t, vector>& sr) {
        sr.insert(sr.begin(), {s[0], s[1], s[0], s[1], 0});
        sr.push_back({t[0], t[1], t[0], t[1], 0});
        
        // Dijkstra
        const int INF = INT32_MAX;
        int n = sr.size();
        vector dist(n, INF);// record min dist  {sr[0][0], sr[0][1]} to {sr[*][2], sr[*][3]} 
        vector vis(n, false);
        dist[0] = 0;
        
        for (int i = 0; i < n; i++) {
            int minDist = INF;
            int u = -1;
            for (int j = 0; j < n; j++) {//每次取出未访问结点中距离最小的:u
                if (!vis[j] && dist[j] < minDist) {
                    minDist = dist[j];
                    u = j;
                }
            }
            if (u == -1) break;
            vis[u] = true;//用该结点更新其他结点的距离
            for (int v = 0; v < n; v++) {//接着我们看与u连接的点
                if (u == v) continue;
                int toStartOfv = getCost(sr[u][2], sr[u][3], sr[v][0], sr[v][1]);
                int alt = dist[u] + toStartOfv + min(sr[v][4], getCost(sr[v][0], sr[v][1], sr[v][2], sr[v][3]));
                dist[v] = min(dist[v], alt);
            }
        }
        return dist[n-1];
    }
};




cg

  • 有dfs的版本https://zhuanlan.zhihu.com/p/554749044
#include 
using namespace std;
//从城市1到城市5最短路径为多少?
int mp[105][105];//图
int vis[105];//测试数组
int x, y, r;
int n; int m;
int minx = 1000000;
void dfs(int step, int sum) {
	if (sum > minx) {
		return;
	}
	if (step == n) {//当扫描到最后一个城市时		
		if(sum> n>>m;
	while (m--) {
		cin >> x >> y >> r;
		mp[x][y] = r;//该图为有向图,是由x到y的距离
	}
	dfs(1, 0);
	cout << minx << endl;
}

LeetCode 2662.前往目标的最小代价 DJ_第1张图片- Floyed

void floyed(){
    for (int k = 1; k <= n; k++) {//从1到n依次各点进行中转
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                if (e[i][j] > e[i][k] + e[k][j]) {//如果该路径更短,更新成该路径
                    e[i][j] = max(e[i][j],e[i][k] + e[k][j]);
                }
            }
        }
    }
}
  • 建图 & 最短路

你可能感兴趣的:(笔记,leetcode,算法,职场和发展)