有一个含n个顶点(编号为0~n-1)的带权图,用邻接矩阵数组A表示,采用分枝限界法求从起点s到目标点t的最短路径长度,以及具有最短路径长度的路径条数,C++实现
时间: 2024-05-12 20:13:45 浏览: 91
数据结构-c语言-带main函数-图7.2-图的存储结构-图的邻接矩阵的创建-有向图。
5星 · 资源好评率100%
以下是C++实现代码:
```c++
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int MAXN = 100;
const int INF = 0x3f3f3f3f;
int n, s, t;
int A[MAXN][MAXN]; // 邻接矩阵
int dist[MAXN]; // 存储起点到各个点的最短距离
int cnt[MAXN]; // 存储起点到各个点的最短路径数目
bool vis[MAXN]; // 标记节点是否被访问
struct Node {
int u, d;
bool operator < (const Node& other) const {
return d > other.d; // 按照d升序排列,优先队列默认是大根堆,所以需要反过来
}
};
void Dijkstra() {
memset(dist, INF, sizeof(dist));
memset(cnt, 0, sizeof(cnt));
memset(vis, false, sizeof(vis));
dist[s] = 0;
cnt[s] = 1;
priority_queue<Node> pq;
pq.push({s, dist[s]});
while (!pq.empty()) {
int u = pq.top().u;
pq.pop();
if (vis[u]) continue;
vis[u] = true;
for (int v = 0; v < n; v++) {
if (A[u][v] != INF && !vis[v]) {
if (dist[v] > dist[u] + A[u][v]) {
dist[v] = dist[u] + A[u][v];
cnt[v] = cnt[u];
pq.push({v, dist[v]});
} else if (dist[v] == dist[u] + A[u][v]) {
cnt[v] += cnt[u];
}
}
}
}
}
int main() {
cin >> n >> s >> t;
memset(A, INF, sizeof(A));
for (int i = 0; i < n; i++) {
A[i][i] = 0;
}
int m;
cin >> m;
while (m--) {
int u, v, w;
cin >> u >> v >> w;
A[u][v] = A[v][u] = w;
}
Dijkstra();
cout << dist[t] << endl;
cout << cnt[t] << endl;
return 0;
}
```
首先定义了一个结构体`Node`,表示节点和到起点的距离。然后使用优先队列来维护当前距离起点最近的节点。每次从队列中取出距离最小的节点`u`,并标记为已经访问。然后遍历`u`的所有邻居`v`,如果`v`未被访问,且从起点到`v`的距离比当前距离小,那么更新`dist[v]`和`cnt[v]`,并将`v`加入队列中。如果从起点到`v`的距离等于当前距离,那么将`cnt[v]`加上`cnt[u]`。
最后输出`dist[t]`和`cnt[t]`即可。
阅读全文