【问题标题】:Why this code for Djikstra's algorithm shows a compilation error using a heap? [closed]为什么 Djikstra 算法的这段代码使用堆显示编译错误? [关闭]
【发布时间】:2015-10-30 19:18:23
【问题描述】:
#include <iostream>
#include <map>
#include <vector>
#include <string>
#include <utility>
#include <algorithm>
#include <stack>
#include <queue>
#include <climits>

using namespace std;

#define ll long long 
#define pb push_back
#define mp make_pair

vector<pair<int,int> > mygraph[100001];
int dist[100001];

void shortestpath(int n, int s);
class heapnode
{
public:
    int vertex;
    int key;
};

struct comp
{
    bool operator()(const heapnode &a, const heapnode &b)
    {
        if (a.key > b.key)
            return true;
        else
            return false;
    }
};

int main (void)
{
    int t,i,j;
    for ( i = 0; i < 100001; i++ )
        dist[i] = -1;
    int a,b,c;
    int foo,n,m,s,e;
    cin>>t;
    while (t != 0)
    {
        cin>>n>>m>>s>>e;
        foo = m;
        while (foo != 0)
        {
            cin>>a>>b>>c;
            mygraph[a].pb(mp(b,c));
            mygraph[b].pb(mp(a,c));
            foo--;
        }
        shortestpath(n,s);
        if (dist[e] == -1)
            cout<<"NONE\n";
        else
            cout<<dist[e]<<"\n";
        t--;
    }
    return 0;
}

void shortestpath(int n, int s)
{
    vector<heapnode> myvec;
    myvec.resize(n);
    int i,j,val,weight;
    for ( i = 1; i <= n; i++ )
    {
        myvec[i].vertex = i;
        myvec[i].key = INT_MAX;
    }
    myvec[s].key = 0; // setting the source key to be 0 for Djikstra's
    bool visited[n+1];
    for ( i = 1; i <= n; i++)
        visited[i] = false;  
    make_heap(myvec.begin(),myvec.end(),comp());  // making a min heap
    vector<int> processedver;
    while (processedver.size() != n)
    {
        heapnode obj = myvec.front();  
        pop_heap(myvec.begin(),myvec.end()); // popping the front
        myvec.pop_back(); 
        processedver.pb(obj.vertex); // putting the popped vertex in processedver
        dist[obj.vertex] = obj.key; // setting the value of dist
        int u = obj.vertex; 
        visited[u] = true; // setting it to be true
        auto it = mygraph[u].begin(); 
        while (it != mygraph[u].end())  // updating the vertex neighbours
        {
            for (int j = 1; j <= n; j++)
            {
                if (it->first == j)
                {
                    val = j;
                    weight = it->second;
                    break;
                }       
            }
            if (visited[val] != true && myvec[val].key > (dist[u]+weight))
            {
                myvec[val].key = dist[u]+weight;
            }
            make_heap(myvec.begin(),myvec.end(),comp());
            it++;
        }
    }
}

所以,我尝试使用最小堆实现 Dijkstra 算法。我制作了一个包含顶点号和键号的堆节点。

上面显示了一个编译错误。 http://ideone.com/5VdCLQ

我知道这是堆的问题,但我无法正确找到问题。

【问题讨论】:

  • 你可以使用向量,那你为什么要创建一个包含 100001 个向量的数组呢?为什么不是向量的向量?
  • 使cmp::operator()(...)成为const成员函数。
  • 那些宏是邪恶的。有人需要做的就是创建一个名为ll 的函数或变量,然后繁荣。不编译。
  • @NeilKirk,我正在解决一个问题,输入大小不超过 10^5,因此是这个。虽然我会记住这一点。 :)
  • @RSahu,我到底应该怎么做,请解释原因。 :)

标签: c++ algorithm dijkstra


【解决方案1】:

您的错误源于该行

    pop_heap(myvec.begin(),myvec.end());

由于heapnode 没有operator&lt; 函数,您要么实现它,要么将comp 传递给pop_heap,方法是将其更改为

    pop_heap(myvec.begin(),myvec.end(), comp());

【讨论】:

  • 我为使堆与 pop_heap() 一起工作而制作的 comp()(请参阅我发布的代码)是否也可以使用?
  • @rohansingh,是的。那是您应该使用的唯一一个。在调用make_heap 时使用一种比较两个对象的方法,而在调用pop_heap 时使用另一种比较两个对象的方法是没有意义的。
【解决方案2】:

您需要为class heapnode 定义operatr&lt;(),类似于:

class heapnode
{
public:
    int vertex;
    int key;
    bool operator<(const heapnode& rhs) {
        return key < rhs.key;
    }
};

【讨论】:

  • 如果我想创建一个最小堆,会是key &gt; rhs.key吗?
  • 现在显示运行时错误,请参见:ideone.com/04bE7Z
  • @rohansingh 这将使您的vector&lt;heapnode&gt; myvec 按降序而不是升序排序。所以这一切都取决于make_heap 的工作原理。
  • @rohansingh 我回答了你的操作,我们不是来完全调试你的代码的。
  • @rohansingh,这可以追溯到我的评论。您可以在两个调用中使用 comp - make_heappop_heap - 或者在两个调用中省略 comp 并使用 operator&lt; 函数。
猜你喜欢
  • 2017-11-25
  • 1970-01-01
  • 2013-12-27
  • 2011-12-27
  • 1970-01-01
  • 1970-01-01
  • 2020-08-01
  • 1970-01-01
  • 2021-09-26
相关资源
最近更新 更多