簡體   English   中英

Dijkstra的算法問題

[英]Dijkstra's algorithm question

在下面的代碼中:

#define MAX_VERTICES 260000

#include <fstream>
#include <vector>
#include <queue>
#define endl '\n'
using namespace std;

struct edge {
    int dest;
    int length;
};

bool operator< (edge e1, edge e2) {
    return e1.length > e2.length;
}

int C, P, P0, P1, P2;
vector<edge> edges[MAX_VERTICES];
int best1[MAX_VERTICES];
int best2[MAX_VERTICES];

void dijkstra (int start, int* best) {
    for (int i = 0; i < P; i++) best[i] = -1;
    best[start] = 0;
    priority_queue<edge> pq;
    edge first = { start, 0 };
    pq.push(first);
    while (!pq.empty()) {
        edge next = pq.top();
        pq.pop();
        if (next.length != best[next.dest]) continue;
        for (vector<edge>::iterator i = edges[next.dest].begin(); i != edges[next.dest].end(); i++) {
            if (best[i->dest] == -1 || next.length + i->length < best[i->dest]) {
                best[i->dest] = next.length + i->length;
                edge e = { i->dest, next.length+i->length };
                pq.push(e);
            }
        }
    }
}

int main () {
    ifstream inp("apple.in");
    ofstream outp("apple.out");

    inp >> C >> P >> P0 >> P1 >> P2;
    P0--, P1--, P2--;
    for (int i = 0; i < C; i++) {
        int a, b;
        int l;
        inp >> a >> b >> l;
        a--, b--;
        edge e = { b, l };
        edges[a].push_back(e);
        e.dest = a;
        edges[b].push_back(e);
    }

    dijkstra (P1, best1);           // find shortest distances from P1 to other nodes
    dijkstra (P2, best2);           // find shortest distances from P2 to other nodes

    int ans = best1[P0]+best1[P2];  // path: PB->...->PA1->...->PA2
    if (best2[P0]+best2[P1] < ans) 
        ans = best2[P0]+best2[P1];  // path: PB->...->PA2->...->PA1
    outp << ans << endl;
    return 0;
}

這是什么: if (next.length != best[next.dest]) continue; 用於? 這是為了避免我們遇到循環的情況會給我們相同的答案嗎?

謝謝!

我想你正在考慮你的priority_queue包含2倍相同邊緣的情況,但每個都有不同的“長度”。

如果你推動長度為Y的邊緣X,然后再次推動邊緣X,這可能會發生,但這次它的長度<Y.這就是為什么,如果邊緣的長度不是最低的那么你呢?到目前為止已找到該邊緣,你在該循環的迭代中省略它。

該行是一種處理c ++的priority_queue沒有reduce_key函數這一事實的方法。

也就是說,當你執行pq.push(e)並且堆中已存在具有相同目標的邊時,您希望減少堆中已存在的邊的鍵。 使用c ++的priority_queue並不容易做到這一點,因此處理它的一種簡單方法是允許堆中的多個邊對應於同一目標,並忽略從堆中彈出的第一個(對於每個dest)。

請注意,這會將復雜性從O(ElogV)更改為O(ElogE)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM