c语言编写一个程序exp8-16.cpp,用来求解最短路径问题,假设有n个点,m条无向边,每条边都有长度d和花费p,点的编号是1到n
时间: 2023-10-27 14:04:28 浏览: 145
以下是一个使用Dijkstra算法求解最短路径问题的C++程序:
```c++
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
const int MAXN = 1005;
const int INF = 0x3f3f3f3f;
struct Edge {
int to, dis, cost;
Edge(int v, int w, int c) : to(v), dis(w), cost(c) {}
};
vector<Edge> G[MAXN]; // 邻接表存图
int d[MAXN][MAXN]; // d[i][j] 表示从点i到点j的最短距离
int p[MAXN][MAXN]; // p[i][j] 表示从点i到点j的最短路径上的最小花费
void dijkstra(int s, int n) {
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q; // 小根堆
memset(d, 0x3f, sizeof(d));
memset(p, 0x3f, sizeof(p));
d[s][s] = p[s][s] = 0;
q.push(make_pair(0, s));
while (!q.empty()) {
pair<int, int> x = q.top(); q.pop();
int u = x.second;
if (x.first > d[s][u]) continue; // 剪枝:跳过已经求出最短路的点
for (int i = 0; i < G[u].size(); i++) {
int v = G[u][i].to, w = G[u][i].dis, c = G[u][i].cost;
if (d[s][v] > d[s][u] + w || (d[s][v] == d[s][u] + w && p[s][v] > p[s][u] + c)) {
d[s][v] = d[s][u] + w;
p[s][v] = p[s][u] + c;
q.push(make_pair(d[s][v], v));
}
}
}
}
int main() {
int n, m;
cin >> n >> m;
for (int i = 1; i <= m; i++) {
int u, v, w, c;
cin >> u >> v >> w >> c;
G[u].push_back(Edge(v, w, c));
G[v].push_back(Edge(u, w, c));
}
for (int i = 1; i <= n; i++) dijkstra(i, n); // 求出所有点对之间的最短距离和最小花费
int q;
cin >> q;
while (q--) {
int u, v;
cin >> u >> v;
if (d[u][v] == INF) cout << "-1 -1" << endl; // 不存在路径
else cout << d[u][v] << " " << p[u][v] << endl;
}
return 0;
}
```
程序中使用了邻接表存图,每次调用dijkstra函数求解一个起点到其他所有点的最短距离和最小花费,最后查询时直接输出即可。注意当两点之间不存在路径时需要输出-1 -1。
阅读全文