acwing-383. 观光
考点
- 次短路
题解
1 |
|
思路
次短路的提升题,难点在于要同时记录最短路和次短路的个数。
设第一维代表最短路,第二维代表次短路,
那么d[u][0]
和d[u][1]
分别代表点u
的最短路和次短路长度,
cnt[u][0]
和cnt[u][1]
分别代表点u
的最短路个数和次短路个数。
由于每个点的最短路和次短路的个数不一定相同,
所以还需要在堆中新增一个变量type
代表当前点使用的是最短路还是次短路:
1 | // <路径开销,<节点,类型>> |
设当前节点u
,使用类型type
的长度为dis
,要扩展到节点v
,边权为w
,有如下情况:
如果
d[v][0] > dis + w
,即最短路会被更新那么当前最短路就会变成次短路,当前最短路的个数就会变成次短路的个数:
1
d[v][1] = d[v][0], cnt[v][1] = cnt[v][0], q.push({-d[v][1], {v, 1}});
当前最短路变成
dis + w
,个数等于cnt[u][type]
:1
d[v][0] = dis + w, cnt[v][0] = cnt[u][type], q.push({-d[v][0], {v, 0}});
如果
d[v][0] == dis + w
,当前开销等于最短路,直接新增最短路个数1
cnt[v][0] += cnt[u][type];
如果
d[v][1] > dis + w
且d[v][0] < dis + w
,即次短路会被更新次短路变成
dis + w
,个数等于cnt[u][type]
:1
d[v][1] = dis + w, cnt[v][1] = cnt[u][type], q.push({-d[v][1], {v, 1}});
如果
d[v][1] == dis + w
,当前开销等于次短路,直接新增次短路个数1
cnt[v][1] += cnt[u][type];