【Day53 LeetCode】图论问题

一、图论问题

1、Floyd算法

之前提到的dijkstra算法和Bellman算法都是只能有一个起点,而这题是求多个起点到多个终点的多条最短路径。Floyd算法的思想是动态规划。

dp数组,grid[i][j][k] = m,表示 节点i 到 节点j 以[1...k] 集合中的一个节点为中间节点的最短距离为m。

dp方程,节点i 到 节点j 的最短路径是否经过节点k。若经过,grid[i][j][k] = grid[i][k][k - 1] + grid[k][j][k - 1];若不经过,grid[i][j][k] = grid[i][j][k - 1]。所以,递推方程为grid[i][j][k] = min(grid[i][k][k - 1] + grid[k][j][k - 1], grid[i][j][k - 1])

CPP 复制代码
#include <iostream>
#include <vector>
#include <list>
using namespace std;

int main() {
    int n, m, p1, p2, val;
    cin >> n >> m;

    vector<vector<vector<int>>> grid(n + 1, vector<vector<int>>(n + 1, vector<int>(n + 1, 10005)));  // 因为边的最大距离是10^4
    for(int i = 0; i < m; i++){
        cin >> p1 >> p2 >> val;
        grid[p1][p2][0] = val;
        grid[p2][p1][0] = val; 
    }
    // 开始 floyd
    for (int k = 1; k <= n; k++) {
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                grid[i][j][k] = min(grid[i][j][k-1], grid[i][k][k-1] + grid[k][j][k-1]);
            }
        }
    }
    // 输出结果
    int z, start, end;
    cin >> z;
    while (z--) {
        cin >> start >> end;
        if (grid[start][end][n] == 10005)
            cout << -1 << endl;
        else
            cout << grid[start][end][n] << endl;
    }
}

空间优化,减少dp数组的一个维度,代码如下:

CPP 复制代码
#include <iostream>
#include <vector>
using namespace std;

int main() {
    int n, m, p1, p2, val;
    cin >> n >> m;

    vector<vector<int>> grid(n + 1, vector<int>(n + 1, 10005));  // 因为边的最大距离是10^4

    for(int i = 0; i < m; i++){
        cin >> p1 >> p2 >> val;
        grid[p1][p2] = val;
        grid[p2][p1] = val; 

    }
    // 开始 floyd
    for (int k = 1; k <= n; k++) {
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                grid[i][j] = min(grid[i][j], grid[i][k] + grid[k][j]);
            }
        }
    }
    // 输出结果
    int z, start, end;
    cin >> z;
    while (z--) {
        cin >> start >> end;
        if (grid[start][end] == 10005)
        	cout << -1 << endl;
        else
        	cout << grid[start][end] << endl;
    }
}

2、A star算法

BFS 是没有目的性的 一圈一圈去搜索, 而 A * 是有方向性的去搜索,这个是A算法和BFS最本质的区别。A的方向由启发性函数决定,这部分代码之后补上。

相关推荐
San305 分钟前
从零到一:彻底搞定面试高频算法——“列表转树”与“爬楼梯”全解析
javascript·算法·面试
F_D_Z12 分钟前
最长连续序列(Longest Consecutive Sequence)
数据结构·算法·leetcode
ss27312 分钟前
Java并发编程:DelayQueue延迟订单系统
java·python·算法
JHC00000015 分钟前
118. 杨辉三角
python·算法·面试
WolfGang00732130 分钟前
代码随想录算法训练营Day50 | 拓扑排序、dijkstra(朴素版)
数据结构·算法
业精于勤的牙43 分钟前
浅谈:算法中的斐波那契数(四)
算法
一直都在5721 小时前
数据结构入门:二叉排序树的删除算法
数据结构·算法
白云千载尽1 小时前
ego_planner算法的仿真环境(主要是ros)-算法的解耦实现.
算法·无人机·规划算法·后端优化·ego·ego_planner
Swizard1 小时前
别再只会算直线距离了!用“马氏距离”揪出那个伪装的数据“卧底”
python·算法·ai
flashlight_hi2 小时前
LeetCode 分类刷题:199. 二叉树的右视图
javascript·算法·leetcode