【问题标题】:Dijkstra's algorithm questionDijkstra 算法题
【发布时间】:2011-02-06 19:48:01
【问题描述】:

在下面的代码中:

#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; 用于?是为了避免我们遇到循环会给出与我们已经得到的相同答案的情况吗?

谢谢!

【问题讨论】:

  • 我不知道这个算法,但你的意思是e1.length &lt; e2.length
  • 不,我不是这个意思。这是一种最短路径算法,更短 = 更好。

标签: c++ algorithm graph-theory


【解决方案1】:

该行是处理 c++ 的 priority_queue 没有 reduce_key 函数这一事实的一种方式。

也就是说,当您执行pq.push(e) 并且堆中已经存在具有相同目的地的边缘时,您希望减少堆中已经存在的边缘的键。使用 c++ 的 priority_queue 不容易做到这一点,因此处理它的一种简单方法是允许堆中的多个边对应于相同的目的地,并忽略您从堆中弹出的除第一个(对于每个目的地)之外的所有边。

请注意,这会将复杂性从 O(ElogV) 更改为 O(ElogE)

【讨论】:

    【解决方案2】:

    我猜您正在考虑您的 priority_queue 包含 2 次相同边缘,但每个边缘具有不同“长度”的情况。

    如果您推动长度为 Y 的边 X,然后再次推动边 X,但这次它的长度

    【讨论】:

      猜你喜欢
      • 2014-06-20
      • 1970-01-01
      • 2021-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多