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

    你可能感兴趣的文章
    Python中可用和使用的系统内存?
    查看>>
    python中存根文件(.pyi)的用途是什么?
    查看>>
    Python中实现ASCII码与字符相互转换
    查看>>
    Python中实现获取所有微信好友的头像并拼接成一张图片
    查看>>
    Python中对象的布尔值
    查看>>
    python中对集合的操作
    查看>>
    python中将列表转换为元组的时间复杂度,反之亦然
    查看>>
    Python中布尔表达式的求值
    查看>>
    python中很常用的10个内置函数整理(初学必备)
    查看>>
    python中打印二维列表数据
    查看>>
    python中打散数组shuffle
    查看>>
    Python中执行外部命令
    查看>>
    Python中拼接numpy数组-ChatGPT4o作答
    查看>>
    Python中提示:no module named 'PIL'
    查看>>
    Python中提示:UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position
    查看>>
    python中数据类型存储_浅谈Python中的数据类型
    查看>>
    python中文件最重要的功能是什么-学 Python 都用来干嘛的?
    查看>>
    python中文版语言_高盛最新调查:Python超过汉语成为未来最重要技能,你准备学哪种编程语言?...
    查看>>
    Python中文问题SyntaxError
    查看>>
    Python中方括号和括号括起来的列表有什么区别?
    查看>>