【Leetcode】882. Reachable Nodes In Subdivided Graph 882. 细分图中的可到达结点

1
2
3

解法

我个人觉得就是一种BFS
优先遍历距离近的点,所以不用队列要用优先队列
最开始是一边遍历一边加,而且要考虑到从i往j用的点数,还有从j往i用的点数,以及它们重合了怎么办

class Solution(object):
    def reachableNodes(self, edges, M, N):
        """
        :type edges: List[List[int]]
        :type M: int
        :type N: int
        :rtype: int
        """
        from collections import defaultdict
        from heapq import heappush,heappop
        adj = defaultdict(list)
        for i,j,k in edges:
            adj[i].append((j,k))
            adj[j].append((i,k))
        bfs = [(0,0)]
        ans = 0
        used = defaultdict(lambda:defaultdict(int))
        mark = set()
        while bfs:
            d,i = heappop(bfs)
            # print i,d
            if i in mark:continue
            mark.add(i)
            ans += 1
            for j,k in adj[i]:
                able = k-used[j][i]
                if k>0 and not able:continue
                used[i][j] = min(able,M-d)
                # print i,j,able,used[i][j]
                ans += used[i][j]
                if d+k+1<=M and j not in mark:
                    heappush(bfs,(d+k+1,j))
        return ans

看了答案之后,发现不需要边遍历边加,对于一条边,我们可以算出来从i到j会用a点,从j到i会用b点
a+bk之间取最小值就可以了

class Solution(object):
    def reachableNodes(self, edges, M, N):
        """
        :type edges: List[List[int]]
        :type M: int
        :type N: int
        :rtype: int
        """
        from collections import defaultdict
        from heapq import heappush,heappop
        adj = defaultdict(list)
        for i,j,k in edges:
            adj[i].append((j,k))
            adj[j].append((i,k))
        bfs = [(0,0)]
        used = defaultdict(lambda:defaultdict(int))
        mark = set()
        while bfs:
            d,i = heappop(bfs)
            if d>M:break
            # print i,d
            if i in mark:continue
            mark.add(i)
            for j,k in adj[i]:
                used[i][j] = min(k,M-d)
                if d+k+1<=M and j not in mark:
                    heappush(bfs,(d+k+1,j))
        ans = len(mark)
        for i,j,k in edges:
            ans += min(k,used[i][j]+used[j][i])
        return ans
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值