为什么这个Djikstra算法的代码使用堆显示编译错误?

时间:2015-10-30 19:18:24

标签: c++ algorithm dijkstra

#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++;
        }
    }
}

所以,我尝试使用min heap实现Dijkstra的算法。我创建了一个包含顶点编号和密钥编号的heapnode。

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

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

2 个答案:

答案 0 :(得分:2)

您需要为operatr<()定义class heapnode,例如:

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

答案 1 :(得分:2)

您的错误源于

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

由于operator<没有heapnode功能,您可以将其实现,也可以将comp传递给pop_heap,方法是将其更改为

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