博客
关于我
Codeforces - 1520G-G. To Go Or Not To Go?(全图传送门bfs)
阅读量:406 次
发布时间:2019-03-06

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

为了解决这个问题,我们需要找到从起点到终点的最短路径,可以选择是否使用传送门一次。传送门可以看作是一个特殊的节点,可以在图中使用一次。我们需要计算两种情况:不使用传送门和使用传送门,然后比较这两种情况的最小代价。

方法思路

  • 预处理最短距离:使用 Dijkstra 算法计算从起点到所有节点的最短距离 d1,以及从终点到所有节点的最短距离 d2
  • 不使用传送门的最短路径:直接从起点到终点的最短路径,代价为 d1[n][m]
  • 使用传送门的情况
    • 情况一:传送门只在一个点使用,计算每个点的 d1[i] + d2[i],找出最小值。
    • 情况二:传送门在两个点之间使用,计算每对点 (i, j)d1[i] + a[i][j] + d2[j],找出最小值。
  • 比较两种情况:将情况一和情况二的最小代价与不使用传送门的最短路径比较,取最小者作为最终答案。
  • 解决代码

    import heapqdef main():    import sys    input = sys.stdin.read    data = input().split()    idx = 0    n = int(data[idx])    idx +=1    m = int(data[idx])    idx +=1    w = int(data[idx])    idx +=1    INF = float('inf')    a = [[INF]*(m+1) for _ in range(n+1)]    for i in range(1, n+1):        for j in range(1, m+1):            a[i][j] = int(data[idx])            idx +=1    d1 = [[INF]*(m+1) for _ in range(n+1)]    d2 = [[INF]*(m+1) for _ in range(n+1)]    dirs = [(0,1), (1,0), (0,-1), (-1,0)]    for i in range(1, n+1):        for j in range(1, m+1):            d1[i][j] = INF            d2[i][j] = INF    def dijkstra(start, n, m):        dist = [[INF]*(m+1) for _ in range(n+1)]        dist[start] = 0        heap = []        heapq.heappush(heap, (0, start))        while heap:            d, u = heapq.heappop(heap)            if d > dist[u]:                continue            for dx, dy in dirs:                v = u + dx                if v < 1 or v > n:                    continue                if a[u][v] + d < dist[v]:                    dist[v] = d + a[u][v]                    heapq.heappush(heap, (dist[v], v))        return dist    d1 = dijkstra(1, n, m)    d2 = dijkstra(n, n, m)    min_no_portal = d1[n][m]    min_portal_one = INF    for i in range(1, n+1):        for j in range(1, m+1):            if d1[i][j] >= INF or d2[i][j] >= INF:                continue            cost = d1[i][j] + d2[i][j]            if cost < min_portal_one:                min_portal_one = cost    min_portal_two = INF    for i in range(1, n+1):        for j in range(1, m+1):            if d1[i][j] >= INF or d2[j][i] >= INF:                continue            cost = d1[i][j] + a[i][j] + d2[j][i]            if cost < min_portal_two:                min_portal_two = cost    candidates = []    if min_portal_one != INF:        candidates.append(min_portal_one)    if min_portal_two != INF:        candidates.append(min_portal_two)    if min_no_portal != INF:        candidates.append(min_no_portal)    if not candidates:        print(-1)    else:        min_total = min(candidates)        if min_total > 1e17:            print(-1)        else:            print(min_total)if __name__ == '__main__':    main()

    代码解释

  • 输入处理:读取输入数据,初始化图的边权重。
  • Dijkstra 算法:计算从起点和终点到所有节点的最短距离。
  • 计算情况一:遍历所有点,计算每个点作为传送门的位置时的代价,找出最小值。
  • 计算情况二:遍历所有点对,计算使用传送门的情况的最小代价。
  • 比较结果:将三种情况的最小代价比较,输出最小的结果。
  • 转载地址:http://vadkz.baihongyu.com/

    你可能感兴趣的文章
    Objective-C实现互斥量 (附完整源码)
    查看>>
    Objective-C实现互斥锁同步执行两个线程函数(附完整源码)
    查看>>
    Objective-C实现交易密码算法(附完整源码)
    查看>>
    Objective-C实现亨元模式(附完整源码)
    查看>>
    Objective-C实现人工势场法(附完整源码)
    查看>>
    Objective-C实现人民币金额转换成大写中文(附完整源码)
    查看>>
    Objective-C实现人物动画移动效果(附完整源码)
    查看>>
    Objective-C实现从给定的子串列表返回包含所有可能的列表算法(附完整源码)
    查看>>
    Objective-C实现代理服务器(附完整源码)
    查看>>
    Objective-C实现代理模式(附完整源码)
    查看>>
    Objective-C实现令牌桶算法(附完整源码)
    查看>>
    Objective-C实现以数组形式返回斐波那契数列fibonacci算法(附完整源码)
    查看>>
    Objective-C实现以递归的形式MatrixExponentiation矩阵求幂算法 (附完整源码)
    查看>>
    Objective-C实现以递归的方式实现十进制转二进制算法(附完整源码)
    查看>>
    Objective-C实现仿射变换加解密算法(附完整源码)
    查看>>
    Objective-C实现仿射密码加解密算法(附完整源码)
    查看>>
    Objective-C实现仿射密码算法(附完整源码)
    查看>>
    Objective-C实现众数(附完整源码)
    查看>>
    Objective-C实现优先数调度算法(附完整源码)
    查看>>
    Objective-C实现优先级调度算法(附完整源码)
    查看>>