博客
关于我
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/

    你可能感兴趣的文章
    python3 套接字异常(a byte-like object is required not str)
    查看>>
    python3 实现用户三次输入错误记录黑名单并对该用户登录锁定-day1
    查看>>
    python3 文本变图片
    查看>>
    Python3 查看 com 组件的属性
    查看>>
    python3 案例分享--发邮件
    查看>>
    python3 模板库_Python3 标准库概览_Python教程_我爱模板网 - 提供下载各种免费建站资源,免费网站模板,免费网页特效,让你爱上建站!...
    查看>>
    Python3 求最大/小值及索引值 Numpy
    查看>>
    python3+django使用celery执行某些任务失败的解决方案
    查看>>
    Python3+Requests+Unittest实战系列【一】
    查看>>
    python3+requests+unittest实战系列【一】
    查看>>
    python3+requests+unittest实战系列【二】
    查看>>
    Python3+Requests+Unittest实战系列【二】
    查看>>
    python3----ASCII
    查看>>
    Python3-selenium自动化测试框架,结合HTMLTestRunner测试报告!
    查看>>
    Python3-如何自我更新作为服务运行的应用程序
    查看>>
    Python3.1-网格模拟概念性问题
    查看>>
    Python3.12 解决conda环境libstdc++版本过低问题
    查看>>
    python3.2批量查询IP地址区域
    查看>>
    Python3.5中协程和未来/任务之间的区别?
    查看>>
    python3.5实现socket通讯(TCP)
    查看>>