C++ 迪克斯特拉';s算法问题

C++ 迪克斯特拉';s算法问题,c++,algorithm,graph-theory,C++,Algorithm,Graph Theory,在下面的代码中: #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

在下面的代码中:

#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;
}
#定义最大260000个顶点
#包括
#包括
#包括
#定义endl'\n'
使用名称空间std;
结构边{
int dest;
整数长度;
};
布尔运算符<(边e1,边e2){
返回e1.length>e2.length;
}
intc,P,P0,P1,P2;
向量边[最大顶点];
int best1[最大顶点];
int best2[最大顶点];
void dijkstra(整数开始,整数*最佳){
对于(inti=0;idest]==-1 | | next.length+i->length<最佳[i->dest]){
最佳[i->dest]=next.length+i->length;
边e={i->dest,next.length+i->length};
推力器(e);
}
}
}
}
int main(){
ifstream inp(“苹果in”);
流输出(“苹果输出”);
inp>>C>>P>>P0>>P1>>P2;
P0-,P1-,P2-;
对于(int i=0;i>a>>b>>l;
a--,b--;
边e={b,l};
边缘[a]。推回(e);
e、 dest=a;
边缘[b]。推回(e);
}
dijkstra(P1,best1);//查找P1到其他节点的最短距离
dijkstra(P2,best2);//查找从P2到其他节点的最短距离
int ans=best1[P0]+best1[P2];//路径:PB->…->PA1->…->PA2
if(最佳2[P0]+最佳2[P1]…->PA2->…->PA1

outp我猜您正在考虑这样一种情况:您的优先级队列包含2倍于同一条边,但每个边的“长度”不同


如果推送长度为Y的边X,然后再次推送边X,则可能会发生这种情况,但这次它的长度小于Y。这就是为什么,如果该边的长度不是您迄今为止发现的该边的最低长度,您可以在该循环的迭代中使用它。

该行是处理c++的优先级队列没有优先级这一事实的一种方法一个按键功能

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


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

我不知道这个算法,但你是说
e1.length
?不,我不是这个意思。这是一个最短路径算法,越短越好。