D’Esopo-Pape Algorithm
#最短路
最短路アルゴリズム。負辺のあるグラフにおいてもそこそこ高速に最短路を求めることができる。
負閉路が含まれてはいけない。
平均的には高速だが、最悪は指数時間かかるらしい Ker81 ShW81。
このアルゴリズムでは、次に見る頂点をDequeで管理する(SPFAに類似)
それぞれの頂点について以下の状態を持つ
code:text
distv: 現時点での最短路
in_queuev: Dequeに入っているか
usedv: これまでに最短路が更新されたことがあるか
最短路を更新するとき、Dequeに入っていない頂点であればDequeに入れる
このとき、これまで最短路が更新されたことがなければ末尾に、そうでなければ先頭に入れる(SPFAと異なる点)
感想
SPFAよりちょっと速い(最悪ケースはSPFAの方が良い)
謎ヒューリスティックが謎すぎて謎
in_queueとusedをひとつにまとめる実装が主流らしい
コード
code:rust
fn sssp_pape(graph: &Vec<(usize, i64)>, start: usize) -> Vec<i64> {
let mut dist = vec!std::i64::MAX; graph.len();
let mut in_queue = vec!false; graph.len();
let mut used = vec!false; graph.len();
let mut deque = std::collections::VecDeque::new();
diststart = 0;
in_queuestart = true;
usedstart = true;
deque.push_back(start);
while let Some(u) = deque.pop_front() {
in_queueu = false;
let d = distu;
for &(v, w) in &graphu {
let d2 = d.saturating_add(w);
if distv <= d2 {
continue;
}
distv = d2;
if in_queuev {
continue;
}
in_queuev = true;
if usedv {
deque.push_front(v);
} else {
usedv = true;
deque.push_back(v);
}
}
}
dist
}
参考
https://tjkendev.github.io/procon-library/python/graph/desopo-pape.html
https://cp-algorithms.com/graph/desopo_pape.html
https://www.geeksforgeeks.org/desopo-pape-algorithm-single-source-shortest-path/
http://forskning.diku.dk/PATH05/GoldbergSlides.pdf
https://link.springer.com/article/10.1007/BF01585517
https://web.mit.edu/dimitrib/www/SLF.pdf
そこそこ速いよ!
ABC340 D D’Esopo-Pape (AC)
ABC340 D SPFA (TLE)