int dijkstra(int e[][N], int m, int n) { int i, j, u, v, min; for (i = 0; i < n; i++) { dis[i] = e[m][i]; } for (i = 0; i < n; i++) { book[i] = 0; } book[m] = 1; for (i = 0; i < n - 1; i++) { min = INF; for (j = 0; j < n; j++) { if (book[j] == 0 && dis[j] < min) { min = dis[j]; u = j; } } book[u] = 1; for (v = 0; v < n; v++) { if (e[u][v] < INF) { if (dis[v] > dis[u] + e[u][v]) { dis[v] = dis[u] + e[u][v]; } } } } return dis; }
时间: 2024-02-02 07:03:06 浏览: 50
这是一个实现Dijkstra算法求单源最短路径的函数,输入参数为一个邻接矩阵e,m表示起点,n表示矩阵大小。函数返回一个包含起点到各个顶点最短距离的数组dis。在函数中,首先将起点m到各个顶点的距离初始化为邻接矩阵中m行的数据,然后将起点m加入到已访问的节点中。接着,选择未访问的节点中距离起点最近的一个节点u,将其加入到已访问的节点集合中。然后,遍历以节点u为起点的所有边,更新与节点u相邻的节点v的距离,即若从起点m到达节点u再到达节点v的距离比起点m直接到达节点v的距离更短,则更新dis[v]的值。重复以上过程直到所有节点都被访问过,最终dis数组中存储的即是起点m到各个节点的最短距离。
相关问题
void+Dijkstra(Vertex*+Head,+int+n,+int+s,+int+dist[],int+path[]){ int+S[N],i,+j,+min,+v,+w;+for+(i+=
void Dijkstra(Vertex* Head, int n, int s, int dist[], int path[]) {
int S[N], i, j, min, v, w;
for (i = 0; i < n; i++) {
dist[i] = INFINITY; // 初始化距离为无穷大
S[i] = 0; // 初始化集合S为空集
}
dist[s] = 0; // 起始点到自身的距离为0
for (i = 0; i < n; i++) {
min = INFINITY; // 初始化最小距离为无穷大
for (j = 0; j < n; j++) {
if (S[j] == 0 && dist[j] < min) { // 在集合S之外找到距离最小的顶点
min = dist[j];
v = j;
}
}
S[v] = 1; // 将顶点v加入集合S
for (w = 0; w < n; w++) {
if (S[w] == 0 && dist[v] + G[v][w] < dist[w]) { // 更新其他顶点的最短距离
dist[w] = dist[v] + G[v][w];
path[w] = v; // 记录路径
}
}
}
}
#include <iostream> #include <cstring> using namespace std; const int MAXN = 1000000; const int INF = 0x3f3f3f3f; struct Edge { int to; int w; int next; } edges[MAXN]; int head[MAXN]; int cnt = 0; int n, m; int dis[MAXN]; bool vis[MAXN]; void addEdge(int u, int v, int w) { edges[cnt].to = v; edges[cnt].w = w; edges[cnt].next = head[u]; head[u] = cnt++; } void dijkstra(int start, int end) { memset(vis, 0, sizeof(vis)); for (int i = 1; i <= n; ++i) { dis[i] = INF; } dis[start] = 0; while (!vis[end]) { int min_dis = INF, min_pos = -1; for (int j = 1; j <= n; ++j) { if (!vis[j] && dis[j] < min_dis) { min_dis = dis[j]; min_pos = j; } } if (min_pos == -1) return; vis[min_pos] = true; for (int k = head[min_pos]; k != -1; k = edges[k].next) { int j = edges[k].to; if (!vis[j] && dis[j] > dis[min_pos] + edges[k].w) { dis[j] = dis[min_pos] + edges[k].w; } } } } int main() { int start, end ; memset(head, -1, sizeof(head)); cin >> n >> m>> start >> end; for (int i = 1; i <= m; ++i) { int u, v, w; cin >> u >> v >> w; addEdge(u, v, w); addEdge(v, u, w); } dijkstra(start, end); cout << dis[end] << endl; return 0; }帮我解决这段代码segmentation fault的问题
这段代码在使用 `memset` 函数时有一个问题:memset 函数的第二个参数应该是要初始化的字节数,而不是要初始化的元素个数。因此,在初始化 `vis` 数组时,应该传入 `sizeof(bool) * (n+1)`,而不是 `sizeof(vis)`。同样地,在初始化 `dis` 数组时,应该传入 `sizeof(int) * (n+1)`。
此外,在使用 `head` 数组时也可能出现问题。如果输入的图中有孤立节点,即没有与其他节点相连的节点,那么 `head` 数组中对应的位置就没有被赋值,此时访问该位置会出现未定义的行为。在使用 `head` 数组时,应该先初始化为 -1。
以下是修改后的代码:
```c++
#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 1000000;
const int INF = 0x3f3f3f3f;
struct Edge {
int to;
int w;
int next;
} edges[MAXN];
int head[MAXN];
int cnt = 0;
int n, m;
int dis[MAXN];
bool vis[MAXN];
void addEdge(int u, int v, int w) {
edges[cnt].to = v;
edges[cnt].w = w;
edges[cnt].next = head[u];
head[u] = cnt++;
}
void dijkstra(int start, int end) {
memset(vis, false, sizeof(bool) * (n+1));
memset(dis, INF, sizeof(int) * (n+1));
dis[start] = 0;
while (!vis[end]) {
int min_dis = INF, min_pos = -1;
for (int j = 1; j <= n; ++j) {
if (!vis[j] && dis[j] < min_dis) {
min_dis = dis[j];
min_pos = j;
}
}
if (min_pos == -1) return;
vis[min_pos] = true;
for (int k = head[min_pos]; k != -1; k = edges[k].next) {
int j = edges[k].to;
if (!vis[j] && dis[j] > dis[min_pos] + edges[k].w) {
dis[j] = dis[min_pos] + edges[k].w;
}
}
}
}
int main() {
int start, end;
memset(head, -1, sizeof(head));
cin >> n >> m >> start >> end;
for (int i = 1; i <= m; ++i) {
int u, v, w;
cin >> u >> v >> w;
addEdge(u, v, w);
addEdge(v, u, w);
}
dijkstra(start, end);
if (dis[end] == INF) {
cout << "No path" << endl;
} else {
cout << dis[end] << endl;
}
return 0;
}
```
阅读全文