LeetCode--[广度优先搜索] 847. 访问所有节点的最短路径

847. 访问所有节点的最短路径

给出 graph 为有 N 个节点(编号为 0, 1, 2, …, N-1)的无向连通图。
graph.length = N,且只有节点 i 和 j 连通时,j != i 在列表 graph[i] 中恰好出现一次。
返回能够访问所有节点的最短路径的长度。你可以在任一节点开始和停止,也可以多次重访节点,并且可以重用边。

示例 1:

输入:[[1,2,3],[0],[0],[0]]
输出:4
解释:一个可能的路径为 [1,0,2,0,3]
示例 2:

输入:[[1],[0,2,4],[1,3,4],[2],[1,2]]
输出:4
解释:一个可能的路径为 [0,1,4,2,3]

提示:

1 <= graph.length <= 12
0 <= graph[i].length < graph.length

解答

采用广度优先搜索,记录当前已经访问的节点(最多只有12个节点,用12bit记录)。用队列实现广度优先搜索,判断当前的状态是否曾经访问过,如果曾经访问过就跳过。用一个list存放状态,大小为N*2^N。逐层访问。

# -*- coding: utf-8 -*-
from collections import deque, namedtuple

GraphNode = namedtuple('GraphNode',['id','nodes_visited'])

class Solution:
    def shortestPathLength(self, graph):
        """
        :type graph: List[List[int]]
        :rtype: int
        """
        # 采用广度优先搜索,记录当前已经访问的节点(最多只有12个节点,用12bit记录)
        # 用队列实现广度优先搜索,判断当前的状态是否曾经访问过,如果曾经访问过就跳过
        # 用一个list存放状态,大小为N*2^N
        # 逐层访问

        N = len(graph)
        q = deque()
        # 起始节点
        for n in range(N):
            q.append(GraphNode(n, 1<<n))
        # 所有节点
        all_nodes = 0
        for i in range(N):
            all_nodes = all_nodes | (1<<i)
        # 记录已经访问过的状态
        states_seen = [[ 0 for j in range(pow(2, N))] for i in range(N)]

        # 当前已经访问的长度
        path_length = 0
        while q:
            # 当前层的队列长度
            nq = len(q)
            while nq:
                nq = nq - 1
                cur_node = q.popleft()
                # 判断是否已经访问了所有的节点
                if cur_node.nodes_visited == all_nodes:
                    return path_length
                # 邻接节点
                neighbours = graph[cur_node.id]
                for id in neighbours:
                    nodes_visited = cur_node.nodes_visited
                    # 添加已访问的节点
                    nodes_visited = nodes_visited | (1<<id)
                    # 判断当前的状态是否访问过,若有则跳过,若没有则添加到队列并且更新状态
                    if states_seen[id][nodes_visited]:
                        continue
                    states_seen[id][nodes_visited] = 1
                    q.append(GraphNode(id, nodes_visited))
            path_length = path_length + 1
        return -1

猜你喜欢

转载自blog.csdn.net/u014230646/article/details/81189266