【问题标题】:Error in Dijkstra's shortest path algorithm implementation (using C++ STL)Dijkstra 的最短路径算法实现中的错误(使用 C++ STL)
【发布时间】:2020-11-15 20:58:18
【问题描述】:

我尝试使用 std::priority_queue 在 C++ 中实现 Dijkstra 算法。函数“dijsktra”将输入作为 2 个节点,源顶点和目标顶点。但是,我每次都得到不正确的答案。请帮帮我,告诉我哪里出错了。我的代码-

#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdlib>
#include <stdio.h>
#include <vector>
#include <numeric>
#include <set>
#include <map>
#include <queue>
#define inf 9999999
using namespace std;

map <int,int> vis;
vector <vector <pair <int,int> > > adj(100);
vector <int> dist(100);

void dijkstra(int u,int t)
{
    priority_queue <pair <int,int> > q;
    int b,w,i;
    q.push({0,u});
    vis[u]=1;
    
    while(!q.empty())
    {
        u = q.top().second; q.pop();
        
        if(!vis[u])
        {
            vis[u]=1;
            for(i=0;i<adj[u].size();i++)
            {
                b = adj[u][i].first; w = adj[u][i].second;
                if(dist[b]>dist[u]+w)
                {
                    dist[b] = dist[u] + w;
                    q.push({-dist[b],b});
                }
            }
        }
    }
    
    cout << dist[t];
}


int main()
{
    int i,j,k,n,m,x,y,w,t;
    
    cin >> n >> m;
    for(i=0;i<m;i++)
    {
        cin >> x >> y >> w;
        adj[x].push_back({y,w});
        adj[y].push_back({x,w});
    }
    
    cin >> t;
    
    for(i=1;i<=n;i++)
    {
        dist[i]=inf;
    }
    
    dijkstra(1,t);
}

【问题讨论】:

  • @SaiSreenivas 我试过了,我仍然得到错误的输出(现在输出是 INT_MAX)。优先级队列返回最大元素,但我想要最小元素,这就是我发送 -dist[b] 的原因。

标签: c++ algorithm stl graph-algorithm dijkstra


【解决方案1】:

错误:

由于vis[u] = 1 不允许您进入 for 循环,您的代码无法正常工作。

实际上,在Dijkstra algorithm 中不需要visited array(至少在这种情况下)。但是在这里使用visited array会降低时间复杂度,当有负边缘时会很棘手,所以要小心。

#include <iostream>
#include <vector>
#include <queue>
#define inf 9999999

std::vector <std::vector <std::pair <int,int> > > adj(100);
std::vector <int> dist(100);

void dijkstra(int u,int t)
{
    std::priority_queue <std::pair<int, int>> q;
    int b, w, i;

    q.push({0, u});
    while(!q.empty()) {
        u = q.top().second; 
        q.pop();
        for(i = 0; i < adj[u].size(); i++) {
            b = adj[u][i].first; w = adj[u][i].second;
            if(dist[b] > dist[u] + w) {
                dist[b] = dist[u] + w;
                q.push({-dist[b], b});
            }
        }
    }
    
    std::cout << dist[t];
}


int main()
{
    int i, n, m, x, y, w, t;
    
    std::cin >> n >> m;
    for(i = 0;i < m; i++) {
        std::cin >> x >> y >> w;
        adj[x].push_back({y, w});
        adj[y].push_back({x, w});
    }
    
    std::cin >> t;
    
    for(i = 0; i < n; i++) {
        dist[i] = inf;
    }
     
    // making the source distance to 0
    dist[0] = 0;
    
    dijkstra(0,t);
}

【讨论】:

    【解决方案2】:

    问题是vis[u]=1; 就在q.push({0,u}); 之后。

    因此,检查if(!vis[u])无法通过,不会处理任何节点。

    你应该使用dist[u]=0; 而不是那个。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-31
      • 2016-07-30
      相关资源
      最近更新 更多