Dijkstra のアルゴリズムの実行時の複雑さについて質問があります。(CLRS バージョン 3 の疑似コードを参照):
DIJKSTRA(G, w, s)
1 INITIALIZE-SINGLE-SOURCE(G, s)
2 S ← ∅
3 Q ← V[G]
4 while Q != ∅
5 do u ← EXTRACT-MIN(Q)
6 S ← S ∪ {u}
7 for each vertex v ∈ Adj[u]
8 do RELAX(u, v,w)
行 3 は O(V)、行 5 は合計で O(VlogV) であると理解しています。行 7 は合計で O(E) であり、行 8 は reduce_key() を意味するため、Relax() 操作ごとに logV です。しかし、relax() では、d[v]>d[u]+weight となり、緩和することを決定した後、recrease_key(Q, pos, d[v] を呼び出す前に、キュー Q 内の v の位置を調べるべきではありませんか? ) pos のキーを d[v] に置き換えるには? このルックアップ自体に O(V) のコストがかかることに注意してください。したがって、各 Relax() は、O(logV) ではなく O(V) のコストがかかるはずですよね?
スペースの複雑さに関する質問: キュー Q の頂点を比較するには、距離を 1 つのメンバーとして構造体/クラスの頂点を設計し、距離を比較して頂点を並べ替える operator< などを実装します。しかし、Relax() で dist[v] = dist[u]+weight を実行するには、複製配列 dist[] を定義する必要があるようです。複製配列を定義しない場合、キュー Q で v と u の位置を検索し、それらの距離を取得して確認する必要があります。このように動作すると思われますか?それとも私の実装が良くないのですか?