广度优先搜索:最短距离hackerrank

时间:2016-04-29 18:41:43

标签: python algorithm shortest-path floyd-warshall

给定由N个节点(标记为1到N)组成的无向图,其中节点S表示起始位置,并且图中任意两个节点之间的边长度为6个单位。问题here

需要计算从起始位置(节点S)到图中所有其他节点的最短距离。

解决方案:这显然是最小距离的floyd算法的应用。

我尝试了什么:我尝试了下面的代码,它传递了2个测试用例,但在所有其他测试用例中失败了。对于鬼鬼祟祟的虫子,我的斗智斗勇。我只想提示解决方案。在复杂性方面提供其他解决方法的提示会很好,但我正在寻找当前代码的漏洞。

def short_paths(cost, nodes):
for i in range(1, nodes):
  for j in range(1, nodes):
    for k in range(1, nodes):
      if cost[i][j] > cost[i][k]+cost[k][j]:
        cost[i][j] = cost[i][k]+cost[k][j]
return cost

tests = int(input())
while tests:
  x = input().split(" ")
  nodes, edges = int(x[0]), int(x[1])
  #initialize everything with infinity
  dp = [[1<<31 for i in range(nodes+1)] for i in range(nodes+1)]
  #distance between self is 0
  for i in range(nodes+1):
    dp[i][i] = 0
  while edges:
    p = input().split(" ")
    x, y = int(p[0]), int(p[1])
    #undirected graph
    dp[x][y] = 6
    dp[y][x] = 6
    edges -= 1
  src = int(input())
  dp = short_paths(dp, nodes+1)
  result = []
  for i in range(1, nodes+1):
    if src != i:
      if dp[src][i] == 1<<31:
        result.append("-1")
      else:
        result.append(dp[src][i])
  print(" ".join(str(e) for e in result))
  tests -= 1

2 个答案:

答案 0 :(得分:1)

我认为这些问题存在问题:

for k in range(1, nodes):
  for i in range(1, nodes):
    for j in range(1, nodes):

您应首先迭代k,以使结果正确:

尝试:

function showColumns() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getActiveSheet();
  sheet.showColumns(2,3);   // B-D, three columns starting from 2nd 
  sheet.showColumn(7);      //  G, column number 7
}

function hideColumns() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getActiveSheet();
  sheet.hideColumns(2,3);  // B-D, three columns starting from 2nd
  sheet.hideColumn(7);     // G, column 7
}

由于DP使用以前的结果,结果证明迭代的顺序对于获得正确的结果至关重要。

我记住顺序的方法是认为算法的第k次迭代使用仅从位置1到k的中间节点计算从i到j的最短路径。

然而,对于这个问题,这个O(N ^ 3)方法将超时。更好的方法是从起始位置执行广度优先搜索,而不是N + M的复杂性。

答案 1 :(得分:1)

import queue 

def BFS(s):
    q = queue.Queue()
    q.put(s)
    visited[s] = True
    dist[s] = 0

    while not q.empty():
        u = q.get()
        for v in graph[u]:
            if not visited[v]:
                visited[v] = True
                q.put(v)
                dist[v] = dist[u] + 1

Q = int(input())
for _ in range(Q):
    n, m = map(int, input().split())

    graph = [[] for i in range(n)]
    visited = [False for i in range(n)]
    dist = [-1 for i in range(n)]

    for i in range(m):
        u, v = map(lambda x: int(x) - 1, input().split())
        graph[u].append(v)
        graph[v].append(u)
    s = int(input()) - 1

    BFS(s)
    for i in range(n):
        if i == s:
            continue
        print(dist[i]*6 if dist[i] != -1 else '-1', end = ' ')
    print()

只需使用常规BFS