AcWing 1134. 最短路计数
原题链接
中等
作者:
皓首不倦
,
2020-08-14 16:40:18
,
所有人可见
,
阅读 419
'''
先用SPFA求一遍每个点的最短路路径长度,根据每个点的最短路长度和其
邻接点的最短路长度可以确定拓扑序,顺着拓扑序逆序做一次DP即可
'''
from collections import deque
class SPFA:
def __init__(self, start_node, edges, is_directed, max_node_num):
self.edges = edges[::]
self.start_node = start_node
self.is_directed = is_directed
self.max_node_num = max_node_num
def getMinPathLen(self):
return self.getMinInfo()
def getMinInfo(self):
link = {}
dis = [0x7fffffff] * (self.max_node_num+1)
dis[self.start_node] = 0
for a, b, w in self.edges:
if not self.is_directed:
if w < 0:
return None
if a not in link:
link[a] = []
if b not in link:
link[b] = []
link[a].append((b, w))
link[b].append((a, w))
else:
if a not in link:
link[a] = []
link[a].append((b, w))
updated_nodes = deque()
updated_nodes.append(self.start_node)
in_que = [0] * (self.max_node_num + 1)
in_que[self.start_node] = 1
iter_times = 0
while iter_times < self.max_node_num:
update_flag = False
node_num = len(updated_nodes)
for _ in range(node_num):
a = updated_nodes.popleft()
in_que[a] = 0
if a not in link:
continue
for b, w in link[a]:
new_dis = 0x7fffffff if dis[a] == 0x7fffffff else dis[a] + w
if new_dis < dis[b]:
dis[b] = new_dis
update_flag = True
if in_que[b] == 0:
in_que[b] = 1
updated_nodes.append(b)
iter_times += 1
if iter_times == self.max_node_num:
if update_flag:
return None
if not update_flag:
break
return [dis[node] for node in range(0, self.max_node_num+1)]
n, m = map(int, input().split())
link = [[] for i in range(n+1)]
edges = []
for i in range(m):
a, b = map(int, input().split())
link[a].append(b)
link[b].append(a)
edges.append((a, b, 1))
min_len = SPFA(1, edges=edges, is_directed=False, max_node_num=n).getMinPathLen()
from functools import lru_cache
@lru_cache(typed=False, maxsize=12800000)
def dp(i):
if min_len[i] == 0x7fffffff:
return 0
if i == 1:
return 1
ans = 0
for ne in link[i]:
if min_len[ne] + 1 == min_len[i]:
ans += dp(ne)
return ans
for i in range(1, n+1):
print(dp(i) % 100003)