Dijkstra最短路径,最小步骤

时间:2015-05-23 20:02:05

标签: c++ c++11 graph dijkstra

我需要实现一个程序,该程序给出一个弧形正成本的有向图,打印从x到y的最小成本,以及从x到y的所有路径的最小步数以及最低成本。 我编写了一个程序来执行该操作,但有时它需要一条没有最小步骤数的路径。 这是我的代码:

#include <iostream>
#include <vector>
#include <queue>
#include <climits>

using namespace std;

typedef pair<int, int> Warc;
typedef vector<vector<Warc>> Wgraph;

int dijkstra(const Wgraph& g, int x, int y, vector<int>& p) {
  int n = g.size();
  vector<int> d(n, INT_MAX); //costs
  p = vector<int>(n, -1); //parent of each vertice
  d[x] =0;
  vector<bool> S(n, false);
  priority_queue<Warc, vector<Warc>, greater<Warc>> Q;
  Q.push(Warc(0, x));
  while(not Q.empty()) {
    int u = Q.top().second;
    Q.pop();
    if(u == y) return d[u];
    if(not S[u]) {
      S[u] = true;
      for(Warc a : g[u]) {
        int v = a.second;
        int c = a.first;
        if(d[v] > d[u] + c) {
         d[v] = d[u] + c;
         p[v] = u;
         Q.push(Warc(d[v], v));
       }
      }
    }
  }
  return -1;
}

int main() {
  int n; //# of vertices
  while(cin >> n) {
    int m; //# of arcs
    cin >> m;
    Wgraph g(n);
    for(int i = 0; i<m; ++i) {
      int u, v;
      int c;
      cin >> u >> v >> c; // arc: u->v with cost C
      g[u].push_back(make_pair(c, v));
    }
    int x, y;
    cin >> x >> y; //origin and end
    vector<int> p; //p[i]= parent of vertice i
    int path = dijkstra(g, x, y, p);
    if(path == -1) cout << "no path from " << x << " to " << y << endl;
    else {
        int s = 0;
        int i = y;
        while(i != x) {
            ++s;
            i = p[i];
        }
        cout << "cost " << path-s << ", " << s << " step(s)" << endl;
    }
  }
}

感谢。

1 个答案:

答案 0 :(得分:0)

问题是您只考虑优先级队列中的距离。结果,将使用随机的最后一条边来完成路径,但只考虑其中一条。您可以创建一个更高级的距离,除了距离之外还考虑路径的长度:主要权重是距离,但是对于相等的距离,您可以考虑将来自较短路径的边缘缩短。

请注意,您的算法具有错误的复杂性:它具有复杂度[May 22 15:37:04] VERBOSE[1920] chan_sip.c: <--- SIP read from UDP:10.52.102.31:5060 ---> ACK sip:BB12345@10.52.151.211;transport=UDP;user=phone;callmode=voice SIP/2.0 From: Vision <sip:30548013597032@10.52.102.31;transport=UDP>;tag=9cf25a88-1f66340a-13c4-50029-782773-a88579d-782773 To: UAS<sip:BB12345@10.52.151.211;transport=UDP;user=phone>;tag=as36f482dd Call-ID: 9ce87088-1f66340a-13c4-50029-782773-3ff6c107-782773 CSeq: 1 ACK Via: SIP/2.0/UDP 10.52.102.31:5060;branch=z9hG4bK-782773-d55a1c81-68f38a62 Max-Forwards: 70 Contact: <sip:30548013597032@10.52.102.31:5060;transport=UDP> Content-Length: 0 <-------------> [May 22 15:37:04] VERBOSE[1920] chan_sip.c: --- (9 headers 0 lines) --- [May 22 15:37:36] VERBOSE[1920] chan_sip.c: Really destroying SIP dialog '9ce87088-1f66340a-13c4-50029-782773-3ff6c107-782773' Method: ACK [May 22 15:48:01] VERBOSE[1920] chan_sip.c: <--- SIP read from UDP:10.52.102.31:5060 ---> INVITE sip:BB12345@10.52.151.211;transport=UDP;user=phone;callmode=voice SIP/2.0 From: Vision <sip:30548013597032@10.52.102.31;transport=UDP>;tag=9ceee4e8-1f66340a-13c4-50029-782a0b-37323354-782a0b To: UAS<sip:BB12345@10.52.151.211;transport=UDP;user=phone> Call-ID: 9ce94dc8-1f66340a-13c4-50029-782a0b-29a57f4e-782a0b CSeq: 1 INVITE Via: SIP/2.0/UDP 10.52.102.31:5060;branch=z9hG4bK-782a0b-d5643be0-14c1d94d P-Asserted-Identity: <sip:30548013597032@10.52.102.31> Privacy: none Max-Forwards: 70 Supported: 100rel Allow: INVITE,ACK,CANCEL,BYE,OPTIONS,INFO,REFER,PRACK,UPDATE Contact: <sip:30548013597032@10.52.102.31:5060;transport=UDP> Content-Type: application/sdp Content-Length: 317 v=0 o=vision 2890844526 2890844526 IN IP4 10.52.102.31 s=VisionSession c=IN IP4 10.52.102.32 t=0 0 m=audio 10340 RTP/AVP 0 8 98 96 c=IN IP4 10.52.102.32 a=sendrecv a=ptime:20 a=rtpmap:0 PCMU/8000/1 a=rtpmap:8 PCMA/8000/1 a=rtpmap:98 AMR/8000/1 a=rtpmap:96 telephone-event/8000/1 a=fmtp:98 octet-align=1 <-------------> [May 22 15:48:01] VERBOSE[1920] chan_sip.c: --- (14 headers 14 lines) --- [May 22 15:48:01] VERBOSE[1920] chan_sip.c: Sending to 10.52.102.31:5060 (no NAT) [May 22 15:48:01] VERBOSE[1920][C-0000003e] chan_sip.c: Sending to 10.52.102.31:5060 (no NAT) [May 22 15:48:01] VERBOSE[1920][C-0000003e] chan_sip.c: Using INVITE request as basis request - 9ce94dc8-1f66340a-13c4-50029-782a0b-29a57f4e-782a0b [May 22 15:48:01] VERBOSE[1920][C-0000003e] chan_sip.c: No matching peer for '30548013597032' from '10.52.102.31:5060' [May 22 15:48:01] VERBOSE[1920][C-0000003e] netsock2.c: == Using SIP RTP CoS mark 5 [May 22 15:48:01] VERBOSE[1920][C-0000003e] chan_sip.c: Found RTP audio format 0 [May 22 15:48:01] VERBOSE[1920][C-0000003e] chan_sip.c: Found RTP audio format 8 [May 22 15:48:01] VERBOSE[1920][C-0000003e] chan_sip.c: Found RTP audio format 98 [May 22 15:48:01] VERBOSE[1920][C-0000003e] chan_sip.c: Found RTP audio format 96 [May 22 15:48:01] VERBOSE[1920][C-0000003e] chan_sip.c: Found audio description format PCMU for ID 0 [May 22 15:48:01] VERBOSE[1920][C-0000003e] chan_sip.c: Found audio description format PCMA for ID 8 [May 22 15:48:01] VERBOSE[1920][C-0000003e] chan_sip.c: Found unknown media description format AMR for ID 98 [May 22 15:48:01] VERBOSE[1920][C-0000003e] chan_sip.c: Found audio description format telephone-event for ID 96 [May 22 15:48:01] VERBOSE[1920][C-0000003e] chan_sip.c: Capabilities: us - (gsm|ulaw|alaw|h263|testlaw), peer - audio=(ulaw|alaw)/video=(nothing)/text=(nothing), combined - (ulaw|alaw) [May 22 15:48:01] VERBOSE[1920][C-0000003e] chan_sip.c: Non-codec capabilities (dtmf): us - 0x1 (telephone-event|), peer - 0x1 (telephone-event|), combined - 0x1 (telephone-event|) [May 22 15:48:01] VERBOSE[1920][C-0000003e] chan_sip.c: Peer audio RTP is at port 10.52.102.32:10340 [May 22 15:48:01] VERBOSE[1920][C-0000003e] chan_sip.c: Looking for BB12345 in public (domain 10.52.151.211) [May 22 15:48:01] VERBOSE[1920][C-0000003e] chan_sip.c: list_route: hop: <sip:30548013597032@10.52.102.31:5060;transport=UDP> [May 22 15:48:01] VERBOSE[1920][C-0000003e] chan_sip.c: <--- Transmitting (no NAT) to 10.52.102.31:5060 ---> SIP/2.0 100 Trying Via: SIP/2.0/UDP 10.52.102.31:5060;branch=z9hG4bK-782a0b-d5643be0-14c1d94d;received=10.52.102.31 From: Vision <sip:30548013597032@10.52.102.31;transport=UDP>;tag=9ceee4e8-1f66340a-13c4-50029-782a0b-37323354-782a0b To: UAS<sip:BB12345@10.52.151.211;transport=UDP;user=phone> Call-ID: 9ce94dc8-1f66340a-13c4-50029-782a0b-29a57f4e-782a0b CSeq: 1 INVITE Server: Asterisk PBX 11.16.0 Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE Supported: replaces, timer Contact: <sip:BB12345@10.52.151.211:5060> Content-Length: 0 <------------> [May 22 15:48:01] VERBOSE[44997][C-0000003e] pbx.c: -- Executing [BB12345@public:1] Goto("SIP/10.52.102.31-00000034", "vivek_star,BB12345,1") in new stack [May 22 15:48:01] VERBOSE[44997][C-0000003e] pbx.c: -- Goto (vivek_star,BB12345,1) [May 22 15:48:01] VERBOSE[44997][C-0000003e] pbx.c: -- Executing [BB12345@vivek_star:1] Ringing("SIP/10.52.102.31-00000034", "") in new stack [May 22 15:48:01] VERBOSE[44997][C-0000003e] chan_sip.c: <--- Transmitting (no NAT) to 10.52.102.31:5060 ---> SIP/2.0 180 Ringing Via: SIP/2.0/UDP 10.52.102.31:5060;branch=z9hG4bK-782a0b-d5643be0-14c1d94d;received=10.52.102.31 From: Vision <sip:30548013597032@10.52.102.31;transport=UDP>;tag=9ceee4e8-1f66340a-13c4-50029-782a0b-37323354-782a0b To: UAS<sip:BB12345@10.52.151.211;transport=UDP;user=phone>;tag=as415e880a Call-ID: 9ce94dc8-1f66340a-13c4-50029-782a0b-29a57f4e-782a0b CSeq: 1 INVITE Server: Asterisk PBX 11.16.0 Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE Supported: replaces, timer Contact: <sip:BB12345@10.52.151.211:5060> Content-Length: 0 <------------> [May 22 15:48:01] VERBOSE[44997][C-0000003e] pbx.c: -- Executing [BB12345@vivek_star:2] Wait("SIP/10.52.102.31-00000034", "7") in new stack [May 22 15:48:08] VERBOSE[44997][C-0000003e] pbx.c: -- Executing [BB12345@vivek_star:3] Hangup("SIP/10.52.102.31-00000034", "SIP/10.52.102.31-00000034") in new stack [May 22 15:48:08] WARNING[44997][C-0000003e] pbx.c: Invalid cause given to Hangup(): "SIP/10.52.102.31-00000034" [May 22 15:48:08] VERBOSE[44997][C-0000003e] pbx.c: == Spawn extension (vivek_star, BB12345, 3) exited non-zero on 'SIP/10.52.102.31-00000034' [May 22 15:48:08] VERBOSE[44997][C-0000003e] pbx.c: -- Executing [h@vivek_star:1] NoOp("SIP/10.52.102.31-00000034", "vivek star test") in new stack [May 22 15:48:08] VERBOSE[44997][C-0000003e] pbx.c: -- Executing [h@vivek_star:2] Wait("SIP/10.52.102.31-00000034", "7") in new stack [May 22 15:48:08] VERBOSE[44997][C-0000003e] pbx.c: == Spawn extension (vivek_star, h, 2) exited non-zero on 'SIP/10.52.102.31-00000034' [May 22 15:48:08] VERBOSE[44997][C-0000003e] chan_sip.c: Scheduling destruction of SIP dialog '9ce94dc8-1f66340a-13c4-50029-782a0b-29a57f4e-782a0b' in 32000 ms (Method: INVITE) [May 22 15:48:08] VERBOSE[44997][C-0000003e] chan_sip.c: <--- Reliably Transmitting (no NAT) to 10.52.102.31:5060 ---> SIP/2.0 603 Declined Via: SIP/2.0/UDP 10.52.102.31:5060;branch=z9hG4bK-782a0b-d5643be0-14c1d94d;received=10.52.102.31 From: Vision <sip:30548013597032@10.52.102.31;transport=UDP>;tag=9ceee4e8-1f66340a-13c4-50029-782a0b-37323354-782a0b To: UAS<sip:BB12345@10.52.151.211;transport=UDP;user=phone>;tag=as415e880a Call-ID: 9ce94dc8-1f66340a-13c4-50029-782a0b-29a57f4e-782a0b CSeq: 1 INVITE Server: Asterisk PBX 11.16.0 Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE Supported: replaces, timer Content-Length: 0 <------------> [May 22 15:48:08] VERBOSE[1920] chan_sip.c: <--- SIP read from UDP:10.52.102.31:5060 ---> ACK sip:BB12345@10.52.151.211;transport=UDP;user=phone;callmode=voice SIP/2.0 From: Vision <sip:30548013597032@10.52.102.31;transport=UDP>;tag=9ceee4e8-1f66340a-13c4-50029-782a0b-37323354-782a0b To: UAS<sip:BB12345@10.52.151.211;transport=UDP;user=phone>;tag=as415e880a Call-ID: 9ce94dc8-1f66340a-13c4-50029-782a0b-29a57f4e-782a0b CSeq: 1 ACK Via: SIP/2.0/UDP 10.52.102.31:5060;branch=z9hG4bK-782a0b-d5643be0-14c1d94d Max-Forwards: 70 Contact: <sip:30548013597032@10.52.102.31:5060;transport=UDP> Content-Length: 0 <-------------> [May 22 15:48:08] VERBOSE[1920] chan_sip.c: --- (9 headers 0 lines) --- [May 22 15:48:40] VERBOSE[1920] chan_sip.c: Really destroying SIP dialog '9ce94dc8-1f66340a-13c4-50029-782a0b-29a57f4e-782a0b' Method: ACK 而不是O(m log m)O(n log n)是节点数,n是边数)因为您将边缘存储在优先级队列中而不是节点中。 Dijstra的算法仅在存储节点并根据需要调整其在优先级队列中的位置时才有效 - m不支持的操作。