Dijkstra 算法,“旅游规划”,另一种方式拯救詹姆斯邦德

“旅游规划”的题面如下:

有了一张自驾旅游路线图,你会知道城市间的高速公路长度、以及该公路要收取的过路费。
现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径。
如果有若干条路径都是最短的,那么需要输出最便宜的一条路径。

输入格式:
输入说明:输入数据的第1行给出4个正整数N、M、S、D,其中N(2≤N≤500)是城市的个数,顺便假设城市的编号为0~(N−1);
M是高速公路的条数;S是出发地的城市编号;D是目的地的城市编号。
随后的M行中,每行给出一条高速公路的信息,分别是:城市1、城市2、高速公路长度、收费额,中间用空格分开,数字均为整数且不超过500。
输入保证解的存在。

输出格式:
在一行里输出路径的长度和收费总额,数字间以空格分隔,输出结尾不能有多余空格。

输入样例:
4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20

2 3 1 20

输出样例:

3 40

 

这类给出点之间的关系并给出确定的起点,要求最短路径的问题,适用 Dijkstra 算法求解。

一般点使用序号表示,给出边长度 (这里是路程和花费) 的场合,可以使用邻接矩阵存储图的信息。

Dijkstra 算法保证访问包含起点在内且与起点连通的所有图中的点。每次访问一个点时,寻找当下所有未访问点中离起点最近的那一个,然后判断“如果通过现在访问的点走向那个最近点,会不会比原来的路径更短” 。完全访问所有与起点连通的点后,算法结束。

Dijkstra 算法的时间复杂度主要取决于“寻找当下未访问点中离起点最近的那一个”的方式。

Dijkstra 算法无法处理含负值边的图,存在负值边时会在图中形成一个负值圈,无法找到最短路 (因为加上一个负值总是会让被加的数更小)。


以下是使用 python 解题的代码。受限于算法表示和语言性能,测试点 "最大N和M, 随机完全图" 运行超时,如果使用 C/C++ 表示相同的逻辑则可以通过该测试点。

# 邻接矩阵描述图,有插入边的方法
class Graph:
    INFINITY = 65535

    # 初始化描述为一个值全为无穷大的空图
    def __init__(self, vertex_num):
        self.vertex_num = vertex_num
        self.graph_far = []
        self.graph_cost = []
        
        for i in range(vertex_num):
            self.graph_far.append([self.INFINITY]*vertex_num)
            self.graph_cost.append([self.INFINITY]*vertex_num)

    # 向无向图插入边传入的边信息包含在列表内
    def insert_edge(self, edge):
        start, end, long, cost = edge[0], edge[1], edge[2], edge[3]
        self.graph_far[start][end] = long
        self.graph_far[end][start] = long
        self.graph_cost[start][end] = cost
        self.graph_cost[end][start] = cost


class Dist:
    def __init__(self, it_len, full_val=0):
        self.body = []
        for i in range(it_len):
            self.body.append(full_val)


# 找一个在 dist 中存放路程最短的点,找不到则返回 INFINITY
def find_min_dist(graph, dist, collected):
    min_vertex = graph.INFINITY
    min_dist = graph.INFINITY

    for ver in range(graph.vertex_num):
        if not collected[ver] and dist.body[ver] < min_dist:
            min_dist = dist.body[ver]
            min_vertex = ver

    return min_vertex


# dist 和 cost 分别描述路程和花费
def dijkstra(graph, dist, cost, path, start_city):
    
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值