题目传送门
考试 T3 看到策策就已经鏼鏼发抖了……然而 T2 几乎敲了2h,就没时间了,敲个暴力
10
10
10 分走人……
注意到
k
≤
50
k\le 50
k≤50 ,考虑 DP……
令
dp
[
u
]
[
len
]
\text{dp}[u][\text{len}]
dp[u][len] 表示走过路径比
1
→
u
1\to u
1→u 的最短路多
len
\text{len}
len 长度的路径条数。
令
v
v
v 为
u
u
u 的后继节点,
u
→
v
u\to v
u→v 的权值为
w
w
w,转移是这样的:
dp
[
v
]
[
dis
u
+
len
+
w
−
d
i
s
v
]
=
d
p
[
v
]
[
dis
u
+
len
+
w
−
d
i
s
v
]
+
dp
[
u
]
[
len
]
\text{dp}[v][\text{dis}_u+\text{len}+w-dis_v]={dp}[v][\text{dis}_u+\text{len}+w-dis_v]+\text{dp}[u][\text{len}]
dp[v][disu+len+w−disv]=dp[v][disu+len+w−disv]+dp[u][len]
其中,
dis
i
\text{dis}_i
disi 表示
1
→
i
1\to i
1→i 的最短路径长度。
初值为:
dp
[
1
]
[
0
]
=
1
\text{dp}[1][0]=1
dp[1][0]=1
这样我们会发现这个 DP 转移是存在环的,在最短路上的点和零环上的点都可以在同一层互相转移……
于是我们对最短路径上的边以及零边拿来做拓扑排序,这样更新就有顺序了,在最短路上的边和零边就严格按照拓扑序进行转移。
注意到如果有一个零环位于
1
→
n
1\to n
1→n 的长度为
dis
n
+
k
\text{dis}_n+k
disn+k 的路径上,则路径条数无穷多(绕零环跑无穷圈),输出
−
1
-1
−1。
不过,跑 DFS 进行记忆化搜索可能更快一些……
Code
[NOIP] [最短路] [拓扑排序] [DP] NOIP2017Day1 逛公园
最新推荐文章于 2023-05-27 19:37:34 发布