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;
}