用c++数据结构来解决这个问题,不能使用stl容器,给出C++代码:给一个n (1≤n≤106) 个点m(1≤m≤106) 条边的无向图,求 s 到 t 的最短路的长度。 数据保证,s 出发可以到达 t。
时间: 2024-02-16 07:59:54 浏览: 104
好的,我们可以使用 Dijkstra 算法来解决这个问题。
Dijkstra 算法是一种贪心算法,用于解决带权重的单源最短路径问题。它的基本思想是从源节点开始,每次选择距离源节点最近的一个节点,然后以该节点为中心进行扩展,最终得到源节点到其他所有节点的最短路径。
以下是使用 C++ 实现 Dijkstra 算法的代码:
```c++
#include <iostream>
#include <cstring>
using namespace std;
const int N = 1e6 + 10; // 最大节点数
const int INF = 0x3f3f3f3f; // 无穷大
int n, m; // n个节点,m条边
int s, t; // 源节点s,目标节点t
int h[N], e[N], ne[N], w[N], idx; // 邻接表存储图
int dist[N]; // 存储源节点到各节点的最短距离
bool st[N]; // 存储节点是否已确定最短距离
void add(int a, int b, int c) // 添加一条边a->b,边权为c
{
e[idx] = b;
w[idx] = c;
ne[idx] = h[a];
h[a] = idx++;
}
int dijkstra()
{
memset(dist, 0x3f, sizeof dist);
dist[s] = 0;
for (int i = 0; i < n; i++)
{
int t = -1;
for (int j = 1; j <= n; j++)
if (!st[j] && (t == -1 || dist[j] < dist[t]))
t = j;
st[t] = true;
for (int j = h[t]; j != -1; j = ne[j])
{
int k = e[j];
if (dist[t] + w[j] < dist[k])
dist[k] = dist[t] + w[j];
}
}
return dist[t]; // 返回源节点到目标节点的最短距离
}
int main()
{
cin >> n >> m >> s >> t;
memset(h, -1, sizeof h);
while (m--)
{
int a, b, c;
cin >> a >> b >> c;
add(a, b, c);
add(b, a, c);
}
cout << dijkstra() << endl;
return 0;
}
```
我们通过邻接表来存储图,`h[i]` 存储节点 `i` 的第一条边,`e[j]` 存储边 `j` 的目标节点,`w[j]` 存储边 `j` 的边权,`ne[j]` 存储边 `j` 的下一条边。在添加边的时候,因为是无向图,所以需要添加两条边。
在 Dijkstra 算法中,我们需要记录每个节点到源节点的最短距离,同时需要记录哪些节点已经确定了最短距离。我们使用 `dist` 数组来存储最短距离,使用 `st` 数组来存储节点是否已确定最短距离。在每次扩展时,我们选择距离源节点最近的一个节点进行扩展,然后更新与该节点相邻的节点的最短距离。最终得到的 `dist[t]` 即为源节点到目标节点的最短距离。
以上就是使用 C++ 实现 Dijkstra 算法求解单源最短路径问题的代码。
阅读全文