【Day50 LeetCode】图论问题 Ⅷ

发布于:2025-02-28 ⋅ 阅读:(18) ⋅ 点赞:(0)

一、图论问题 Ⅷ

1、dijkstra算法 堆优化

采用堆来优化,适合节点多的稀疏图。代码如下:

# include<iostream>
# include<vector>
# include<list>
# include<queue>
# include<climits>

using namespace std;

class mycomparison {
public:
    bool operator()(const pair<int, int>& lhs, const pair<int, int>& rhs) {
        return lhs.second > rhs.second;
    }
};

int main(){
    int n, m;
    cin >> n >> m;
    int s, e, v;
    vector<list<pair<int, int>>> grid(n+1);
    for(int i=0; i<m; ++i){
        cin >> s >> e >> v;
        grid[s].push_back(pair<int, int>(e, v));
    }
    vector<int> minDist(n+1, INT_MAX);
    vector<bool> visited(n+1, false);
    int start = 1, end = n;
    minDist[start] = 0;
    priority_queue<pair<int, int>, vector<pair<int, int>>, mycomparison> pq;
    pq.push(pair<int, int>(start, 0));
    while(!pq.empty()){
        // 1、选取源点到未被访问过且距离最近的节点; 
        auto cur = pq.top(); pq.pop();
        if(visited[cur.first])
            continue;
        // 2、将最近节点标记为访问过 
        visited[cur.first] = true;
        // 3、更新非访问节点到源点的距离
        for(auto edge : grid[cur.first]){
            if(!visited[edge.first] && minDist[edge.first] > minDist[cur.first] + edge.second )
                minDist[edge.first] = minDist[cur.first] + edge.second;
                pq.push(pair<int, int>(edge.first, minDist[edge.first]));
        }
    }
    if(minDist[end] < INT_MAX)
        cout << minDist[end] << endl;
    else
        cout << -1 << endl;

    return 0;
}

2、Bellman_ford 算法

权值有负值的图无法采用dijdijkstra算法,这时需要使用Bellman_ford 算法来解决最短路问题。

#include <iostream>
#include <vector>
#include <list>
#include <climits>

using namespace std;

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

    vector<vector<int>> grid;
    for(int i = 0; i < m; i++){
        cin >> p1 >> p2 >> val;
        grid.push_back({p1, p2, val});
    }
    int start = 1, end = n;  

    vector<int> minDist(n + 1 , INT_MAX);
    minDist[start] = 0;
    for (int i = 1; i < n; i++) { // 对所有边 松弛 n-1 次
        for (vector<int> &side : grid) { // 每一次松弛,都是对所有边进行松弛
            int from = side[0]; // 边的出发点
            int to = side[1]; // 边的到达点
            int price = side[2]; // 边的权值
            // 松弛操作 
            // minDist[from] != INT_MAX 防止从未计算过的节点出发
            if (minDist[from] != INT_MAX && minDist[to] > minDist[from] + price) { 
                minDist[to] = minDist[from] + price;  
            }
        }
    }
    if (minDist[end] == INT_MAX)
        cout << "unconnected" << endl; // 不能到达终点
    else
        cout << minDist[end] << endl; // 到达终点最短路径
    return 0;
}

参考资料
代码随想录


网站公告

今日签到

点亮在社区的每一天
去签到