博客
关于我
poj 3026( Borg Maze BFS + Prim)
阅读量:793 次
发布时间:2023-03-03

本文共 3336 字,大约阅读时间需要 11 分钟。

为了解决这个问题,我们需要找到一种方法来估算Borg搜索迷宫的最小成本。迷宫中隐藏着多个外星人(用 'A' 表示),我们需要从起点 'S' 出发,找到所有外星人的最短路径,并确保总成本最小。

方法思路

  • 问题分析:迷宫由空格、墙、外星人和起点组成。目标是从起点找到所有外星人的最短路径,总成本是所有路径的总和。由于迷宫的周围是封闭的,起点不会逃逸。

  • 图论建模:将外星人和起点视为图中的节点,节点之间的边权重是它们之间的最短路径距离。问题转化为找到最小生成树,使得所有节点连接的总权重最小。

  • 算法选择:使用Kruskal算法来构建最小生成树,它适合处理权重从小到大排序的边,并确保不形成环。

  • 步骤

    • 读取输入,确定迷宫结构。
    • 找到起点 'S' 和所有外星人的位置。
    • 对每个外星人进行BFS,计算它到起点的最短路径。
    • 构建节点和边的图,使用Kruskal算法找到最小生成树,计算总权重。
  • 解决代码

    import sys
    from collections import deque
    def main():
    input = sys.stdin.read().split()
    ptr = 0
    t = int(input[ptr])
    ptr += 1
    for _ in range(t):
    n = int(input[ptr])
    m = int(input[ptr+1])
    ptr +=2
    map = []
    a = []
    for i in range(n):
    line = input[ptr]
    ptr +=1
    map.append(list(line))
    for j in range(m):
    if map[i][j] == 'S':
    sx, sy = i+1, j+1
    elif map[i][j] == 'A':
    a.append( (i+1, j+1) )
    # Create nodes: S is 1, A's are 2..n, n+1 is dummy
    # Each A is a node, S is node 1
    node_num = len(a) +1
    # Compute distances from S to each A
    # BFS for each A
    # Create a graph where edge between u and v is the distance
    edges = []
    for u in range(1, node_num+1):
    if u ==1:
    continue
    x, y = a[u-2]
    visited = [[False]*(m+1) for _ in range(n+1)]
    q = deque()
    q.append( (x, y, 0) )
    visited[x][y] = True
    dist = { }
    dist[(x,y)] = 0
    while q:
    cx, cy, d = q.popleft()
    for dx, dy in [(-1,0),(1,0),(0,-1),(0,1)]:
    nx = cx + dx
    ny = cy + dy
    if 1<=nx<=n and 1<=ny<=m and not visited[nx][ny] and map[nx-1][ny-1] != '#':
    visited[nx][ny] = True
    q.append( (nx, ny, d+1) )
    dist[(nx, ny)] = d+1
    # Now, for this A, add edges from 1 to it
    # And edges between other As if needed
    for v in range(2, node_num+1):
    if u ==v:
    continue
    if (u, v) not in edges and (v, u) not in edges:
    edges.append( (min(u,v), max(u,v), dist.get( (u, v), float('inf')) ) )
    # Now, Kruskal's algorithm
    # Sort edges by weight
    edges.sort(key=lambda x: x[2])
    # Disjoint Set Union
    parent = list(range(node_num +1))
    def find(u):
    while parent[u] != u:
    parent[u] = parent[parent[u]]
    u = parent[u]
    return u
    def union(u, v):
    u_root = find(u)
    v_root = find(v)
    if u_root == v_root:
    return False
    parent[v_root] = u_root
    return True
    total =0
    count =0
    for u, v, w in edges:
    if union(u, v):
    total +=w
    count +=1
    if count == node_num-1:
    break
    print(total)
    if __name__ == "__main__":
    main()

    代码解释

  • 读取输入:读取输入数据,解析迷宫结构,找到起点 'S' 和所有外星人的位置。
  • BFS计算最短路径:对每个外星人进行BFS,计算它到起点的最短路径距离。
  • 构建最小生成树:使用Kruskal算法,对节点进行排序和连接,确保不形成环,计算最小生成树的总权重。
  • 输出结果:计算并输出最小搜索成本。
  • 通过这种方法,我们能够有效地找到迷宫中所有外星人的最短路径总和,确保总成本最小。

    转载地址:http://kfxfk.baihongyu.com/

    你可能感兴趣的文章
    POJ 1703 Find them, Catch them
    查看>>
    POJ 1703 Find them, Catch them 并查集
    查看>>
    POJ 1738 An old Stone Game(石子合并)
    查看>>
    POJ 1740 A New Stone Game(博弈)题解
    查看>>
    Qt网络编程之实例二POST方式
    查看>>
    POJ 1765 November Rain
    查看>>
    poj 1860 Currency Exchange
    查看>>
    POJ 1961 Period
    查看>>
    POJ 2019 Cornfields (二维RMQ)
    查看>>
    poj 2057 The Lost House 贪心思想在动态规划上的应用
    查看>>
    poj 2057 树形DP,数学期望
    查看>>
    poj 2112 最优挤奶方案
    查看>>
    Qt编写自定义控件12-进度仪表盘
    查看>>
    SpringBoot主启动原理在SpringApplication类《第六课》
    查看>>
    poj 2186 Popular Cows :求能被有多少点是能被所有点到达的点 tarjan O(E)
    查看>>
    POJ 2186:Popular Cows Tarjan模板题
    查看>>
    POJ 2229 Sumsets(递推,找规律)
    查看>>
    poj 2236
    查看>>
    POJ 2243 Knight Moves
    查看>>
    POJ 2262 Goldbach's Conjecture
    查看>>