2019年秋招笔试--深信服(C++岗)--最短路径

  有A、B、C、D、E、F 6个城市,假如某人驾车,A到B需要12个小时,C到D需要3个小时,B到C需要10个小时,D到E需要4个小时,C到F需要6个小时,F到A需要16个小时,E到F需要2个小时,B到F需要7个小时,C到E需要5个小时,求任意给定的两地之间的最佳驾驶路线。

# 输入描述:
	ABCDEF中任意两个字母,以空格隔开
# 输出描述:
	第一行输出最短时间
	第二行输出最佳路径

# 示例:
输入:
	C E
输出:
	5
	C E

  借鉴其他博客的代码(由于代码出现在很多博客中,不再引用与感谢),由于他们代码python的版本问题,运行一直不通过,经过修改,可得到该题的解。
  解题思路就是Dijkstra算法,选择该代码是因为封装较好,可复用,代码如下:

# 无向图中, 两点间的最短距离
class DijkstraPath():
    def __init__(self, node, node_ls):
        self.node_map = [[0 for _ in range(len(node))] for _ in range(len(node))]
        for x, y, val in node_list:
            self.node_map[node.index(x)][node.index(y)] = val
            self.node_map[node.index(y)][node.index(x)] = val
        self.node_len = len(node)
        self.used_node_list = []
        self.collected_node_dict = {}
    
    def solve(self, from_node, to_node):
        self.from_node = from_node
        self.to_node = to_node
        self._init_dijkstra()
        return self._format_path()
    
    def _init_dijkstra(self):
        self.used_node_list.append(self.from_node)
        # 假设起始节点为-1, 则从from_node到起始节点距离为0
        self.collected_node_dict[self.from_node] = [0, -1]
        for node_index, dic in enumerate(self.node_map[self.from_node]):
            # 如果可到达
            if dic:
                self.collected_node_dict[node_index] = [dic, self.from_node]
        self._foreach_dijkstra()
    
    # 迭代
    def _foreach_dijkstra(self):
        if len(self.used_node_list) == self.node_len - 1:
            return
        for key in list(self.collected_node_dict.keys()):
            val = self.collected_node_dict[key]
            if key not in self.used_node_list and key != to_node:
                self.used_node_list.append(key)
            else:
                continue
            for node_index, dic in enumerate(self.node_map[key]):
                # 更新成较小距离的点
                if dic and node_index in self.collected_node_dict and self.collected_node_dict[node_index][0] > dic + val[0]:
                    self.collected_node_dict[node_index][0] = dic + val[0]
                    self.collected_node_dict[node_index][1] = key
                elif dic and node_index not in self.collected_node_dict:
                    self.collected_node_dict[node_index] = [dic + val[0], key]
        self._foreach_dijkstra()
    
    def _format_path(self):
        node_list = []
        temp_node = self.to_node
        node_list.append((temp_node, self.collected_node_dict[temp_node][0]))
        # 从终点往回查找
        while self.collected_node_dict[temp_node][1] != -1:
            temp_node = self.collected_node_dict[temp_node][1]
            node_list.append((temp_node, self.collected_node_dict[temp_node][0]))
        node_list.reverse()
        return node_list


if __name__ == '__main__':
    node = ['A', 'B', 'C', 'D', 'E', 'F']
    node_list = [('A', 'B', 12), ('C', 'D', 3), ('B', 'C', 10),
                 ('D', 'E', 4), ('C', 'F', 6), ('F', 'A', 16),
                 ('E', 'F', 2), ('B', 'F', 7), ('C', 'E', 5)]
    inp = input().split(' ')
    from_node = node.index(inp[0])
    to_node = node.index(inp[1])
    dijkstraPath = DijkstraPath(node, node_list)
    path = dijkstraPath.solve(from_node, to_node)
    print(path[-1][-1])
    res = ''
    for index, dic in path:
        res += node[index] + ' '
    print(res[:-1])

发布了27 篇原创文章 · 获赞 10 · 访问量 5014

猜你喜欢

转载自blog.csdn.net/l1l1l1l/article/details/101052919