题目大意

个无向图(原始图)中有 n 个节点,编号从 0 到 n – 1 。对每条边增加若干节点构建“细分图”,求解从节点0出发能抵达的不超过距离为maxMove的节点数量。

输入:edges = [[0,1,10],[0,2,1],[1,2,2]], maxMoves = 6, n = 3
输出:13

解题思路

求解原始图上从节点0出发能抵达的不超过距离为maxMove的节点数量,可以直接用BFS/DFS快速解决。本题增加了“细分图”的概念,在每一条边 [\(u_i,v_i\)] 上新增 \(cnt_i\) 个节点,仍然求解新的细分图上可到达节点数量。

  • 分析数据规模,新的图节点数量可达到 10^4 * 10^4 = 10^8,无法直接对细分图建图,然后BFS/DFS。
  • 转换一下思路,可以对原始图上的边作特殊处理,即看作路径长度,那么本题可以转化为最短路问题。
  • 求解从节点0出发到其他所有节点的最短路,记录每条边两个方向走过的距离来处理额外边上的节点,统计所有总距离在最大步长范围内的点即为答案。

代码

class Solution:
    def reachableNodes(self, edges: List[List[int]], maxMoves: int, n: int) -> int:
        # 邻接矩阵
        neighbor = [[] for _ in range(n)]
        # 记录每条边的总长,[u->]方向已经访问过节点数
        new_edges = dict()

        for u, v, w in edges:
            neighbor[u].append((v, w))
            neighbor[v].append((u, w))

            new_edges[(u,v)] = [w, 0]
            new_edges[(v,u)] = [w, 0]


        from queue import PriorityQueue
        q = PriorityQueue()
        # (step, start) 优先队列,按step从小到大排序
        q.put((0, 0))
        vis = [False] * n

        ans = 0
        while not q.empty():
            step, u = q.get()

            if vis[u]:
                continue
            vis[u] = True
            ans += 1

            if step>=maxMoves:
                continue

            for v, w in neighbor[u]:
                if vis[v]:
                    # 检查边上是否有未访问的节点
                    # 剩下未走过的节点数: w-反向走过
                    left_nodes = min(w - new_edges[(v,u)][1], w-new_edges[(u,v)][1])
                    s = min(left_nodes, maxMoves-step)
                    new_edges[(u,v)][1] = s

                    ans += s
                    continue

                if step+w+1<=maxMoves:
                    ans += w
                    # print(u,v, ":", w, ans, step+w+1)
                    q.put((step+w+1, v))
                    new_edges[(u,v)][1] = w
                else:
                    # print(u,v, ":", ans, step, maxMoves-step)
                    ans += maxMoves - step
                    new_edges[(u,v)][1] = maxMoves - step
        
        return ans

后记

简简单单的想法,WA了两发才过。先是对边上节点处理不全面,需要新增走过的距离;然后是u->v的距离应为 step+w+1,put放入节点和步长位置也写反了 。


(完)

原文地址:http://www.cnblogs.com/izcat/p/16927978.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性