Dijkstra - cpp

Dijkstra【cpp模板】

方法一:bfs + 贪心 + 优先级队列

代码:

#include <iostream>
#include <vector>
#include <queue>
#include <string>
using namespace std;

// graph:有权图
// start:起点城市
// end:终点城市
// n:城市数目
// pair<int, int>:first -> cost, second -> city
// path:记录最优路径【需要进一步处理】
int dijkstra(const vector<vector<pair<int, int>>> graph, int start, int end, int n, vector<int>& path) {
    vector<bool> isVisit(n, false); // 记录是否经过这个城市
    vector<int> best(n, INT_MAX);   // 记录最优cost

    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq; // 按cost从小到大取下一个要遍历的城市 // 贪心
    pq.push({0, start});    // 起点cost为0
    
    // bfs
    while (!pq.empty()) {
        auto cur = pq.top(); pq.pop();
        int city = cur.second;  // 当前遍历的城市
        int cost = cur.first;   // 到city目前耗费的cost

        // 如果当前城市是终点城市了,那直接return
        if (city == end) {
            return cost;
        }

        // 如果当前城市已经经过了,那进行下一轮循环
        if (isVisit[city]) {
            continue;
        }
        // 能到这步说明当前城市没经过,那么就在这次设置为true
        isVisit[city] = true;

        // 对于当前城市所连通的每个城市
        for (auto& next : graph[city]) {
            int nextCity = next.second;         // 下一个城市
            int nextCost = cost + next.first;   // 到达下一个城市的总cost

            // 如果下个城市已经经过了,或者如果这一步到达下个城市的总cost要比最优cost大,那么就跳过
            if (isVisit[nextCity] || best[nextCity] <= nextCost) {
                continue;
            }
            pq.push({nextCost, nextCity});
            best[nextCity] = nextCost;

            path[nextCity] = city;  // 从后往前,记录上一个城市
        }
    }
    return -1;  // 说明没连通
}

vector<vector<pair<int, int>>> getGraph(int n) {
    vector<vector<pair<int, int>>> graph(n, vector<pair<int, int>>());
    for (int i = 0; i < n; i++) {
        int city;
        cout << "城市: ";
        cin >> city;
        cout << "邻接: ";
        int cost, nextCity;
        while (cin >> cost >> nextCity) {
            graph[city].push_back({cost, nextCity});
            if (getchar() == '\n') {
                break;
            }
        }
    }
    return graph;
}

string getPath(vector<int>& path, int end) {
    string minPath;
    int preIdx = path[end];
    string ed = to_string(end);
    minPath += ed;
    while (preIdx != -1) {
        string city = to_string(preIdx);
        minPath += (">-" + city);
        preIdx = path[preIdx];
    }
    reverse(minPath.begin(), minPath.end());
    return minPath;
}

int main() {

    // int n = 7;
    cout << "城市数目: ";
    int n;
    cin >> n;
    vector<vector<pair<int, int>>> graph = getGraph(n);

    // graph.push_back({{12, 1}, {16, 5}, {14, 6}});
    // graph.push_back({{12, 0}, {10, 2}, {7, 5}});
    // graph.push_back({{10, 1}, {3, 3}, {5, 4}, {6, 5}});
    // graph.push_back({{3, 2}, {4, 4}});
    // graph.push_back({{5, 2}, {4, 3}, {2, 5}, {8, 6}});
    // graph.push_back({{16, 0}, {7, 1}, {6, 2}, {2, 4}, {9, 6}});
    // graph.push_back({{14, 0}, {8, 4}, {9, 5}});

    int start;
    int end;
    cout << "起点城市: ";
    cin >> start;
    cout << "终点城市: ";
    cin >> end;

    vector<int> path(n, -1);

    int res = dijkstra(graph, start, end, n, path);
    cout << "最优路径的代价: " << res << endl;

    string minPath = getPath(path, end);
    cout << "最优路径: " << minPath << endl;

    return 0;
}

参考资料

用例参考

核心代码参考

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值