数据结构-无向连通图-最短路径(迪杰斯特拉算法)

注:本文采用dijkstra算法对顶点1 (编号最小的点)的最短路径长度,代码在解决问题的本质上并未用到p[]和P[][]数组,只是用来记录 。

Description
设计算法,求出无向连通图中距离顶点1 (编号最小的点)的最短路径长度。其中图的输入序列,举例如下:
输入:
3
1 2 12
1 3 8
2 3 4

其中第一行的“3”表示图的结点数,第二行至最后一行表示边及边上的权值;其中第二行“1 2 12”表示结点1与结点2有边,其权值为2。

输出:
结点1到其余顶点(按照结点编号升序)的最短路径长度。
 
Sample Input
4
1 2 6
1 3 4
1 4 10
2 3 3
2 4 6
3 4 1
 
Sample Output
6 4 5
 
Hint
输出有换行
#include <bits/stdc++.h>
#define Max_size 105
#define INTSIZE 32576
using namespace std;
// p[v]为从v0到其余顶点v的最短路径 D[]为其带权长度
int D[Max_size], P[Max_size];
// 邻接矩阵
typedef struct Arcell
{
    int adj;
} Arcell, adjMa[Max_size][Max_size];
typedef struct
{
    int vexs[Max_size];
    adjMa arcs;
    int vex, arc;
} MG;

void creatMG(MG &G)
{ // 创建无向连通图
    int n, v1, v2, info;
    cin >> n;
    G.vex = n;
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        { // 初始化都为最大值
            G.arcs[i][j].adj = INTSIZE;
        }
    }
    while (cin >> v1 >> v2 >> info)
    { // 包括对称点
        G.arcs[v1][v2].adj = info;
        G.arcs[v2][v1].adj = info;
    }
}
void Shortest(MG G, int v1)
{
    // p[v][w]为1表示w是从v0到v求得最短路径上的顶点
    // final[]为判断是否存在回路的辅助数组 为1时当且仅当v属于S顶点集表示以求得v0到v的最短路径
    int v, w, p[Max_size][Max_size], final[Max_size], i;
    for (v = 1; v <= G.vex; v++)
    {                             // 初始化
        final[v] = 0;             // 没找到
        D[v] = G.arcs[v1][v].adj; // 记录
        for (w = 1; w <= G.vex; w++)
            p[v][w] = 0; // 把所有路径设空
        if (D[v] < INTSIZE)
        { // 表示有直接路径
            p[v][v1] = 1;
            p[v][v] = 1; // v必然是从v0到v的关键结点
        }
    }
    D[v1] = 0;
    final[v1] = 1;               // 初始化v1顶点属于S集
    for (i = 2; i <= G.vex; i++) // 其余n-1结点
    {                            // 开始求v0到每个顶点的最短路径,并加到S集
        int min = INTSIZE;       // 当前距离v0最近距离
        for (w = 1; w <= G.vex; w++)
        {
            if (!final[w])
            { // 未在S中(没有回路)
                if (D[w] < min)
                { // 最近的邻接点
                    v = w;
                    min = D[w];
                }
            }
        }
        final[v] = 1; // 标记加入S
        for (w = 1; w <= G.vex; w++)
        {
            if (!final[w] && (min + G.arcs[v][w].adj < D[w]))
            { // 未在S(无回路)并且最小距离加上权值小于直达 就更新数值
                D[w] = min + G.arcs[v][w].adj;
                P[w] = P[v];
                p[w][w] = 1; // 从v0到w标记
            }
        }
    }
}
int main()
{
    MG G;
    adjMa p;
    creatMG(G);
    Shortest(G, 1);
    int cnt = 0;
    for (int w = 2; w <= G.vex; w++)
    {
        cout << D[w];
        if (cnt != G.vex - 2)
            cout << " ";
        cnt++;
    }
    cout << "\n";
    return 0;
}

 

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
您好!要实现有向的单源最路径斯特算法,可以按照以下步骤进行: 1. 创建一个表示有向数据结构,可以使用邻接矩阵或邻接表来存储的信息。这里我们使用邻接表进行演示。 ```python class Graph: def __init__(self, vertices): self.V = vertices self.graph = [[] for _ in range(vertices)] def add_edge(self, u, v, w): self.graph[u].append((v, w)) ``` 2. 实现斯特算法的函数,接受和起始节点作为参数,并返回从起始节点到所有其他节点的最路径长度。 ```python import sys def dijkstra(graph, src): dist = [sys.maxsize] * graph.V dist[src] = 0 visited = [False] * graph.V for _ in range(graph.V): u = min_distance(dist, visited) visited[u] = True for v, w in graph.graph[u]: if not visited[v] and dist[u] != sys.maxsize and dist[u] + w < dist[v]: dist[v] = dist[u] + w return dist def min_distance(dist, visited): min_dist = sys.maxsize min_index = -1 for v in range(len(dist)): if not visited[v] and dist[v] < min_dist: min_dist = dist[v] min_index = v return min_index ``` 3. 使用上述代码,创建一个并调用斯特算法函数来计算最路径。 ```python g = Graph(5) g.add_edge(0, 1, 6) g.add_edge(0, 3, 1) g.add_edge(1, 2, 5) g.add_edge(1, 3, 2) g.add_edge(1, 4, 2) g.add_edge(2, 4, 1) g.add_edge(4, 3, 1) src = 0 distances = dijkstra(g, src) print("最路径长度:") for i in range(g.V): print(f"从节点 {src} 到节点 {i} 的最路径长度为: {distances[i]}") ``` 这样,您就可以使用斯特算法找到有向中从给定起始节点到所有其他节点的最路径长度了。请注意,上述代码中使用了 sys.maxsize 表示无穷大,您可以根据自己的需求进行调整。希望对您有所帮助!如有任何问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值