解法
我个人觉得就是一种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+b
和k
之间取最小值就可以了
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