具有邻接列表和优先级队列的Dijkstra算法

时间:2014-05-01 03:44:59

标签: c++ algorithm list queue priority-queue

#include <iostream>
#include <fstream>
#include <functional>
#include <climits>
#include <vector>
#include <queue>
#include <list>


using namespace std;

struct Vertices {
    int vertex;
    int weight;
    Vertices(int v, int w) : vertex(v), weight(w) { };
    Vertices() { }
};

class CompareGreater {
    public:
        bool const operator()(Vertices &nodeX, Vertices &nodeY) {
            return (nodeX.weight > nodeY.weight) ;
        }
};

vector< list<Vertices> > adj;
vector<int> weights;
priority_queue<Vertices, vector<Vertices>, CompareGreater> Q;

int nrVertices, nrEdges;

void readData();
void Dijkstra(Vertices);
void writeData();

void writeData() {
    ifstream out;
    out.open("graph.txt");

    weights.resize(1);
    for (vector<int>::iterator it = weights.begin()+1; it != weights.end(); ++it) {
        cout << (*it) << " ";
    }

    out.close();
}

void readData() {
    ifstream myFile;
    myFile.open("graph.txt");

    int nodeX, nodeY, weight;

    myFile >> nrVertices >> nrEdges;

    adj.resize(nrVertices+1);
    weights.resize(1);

    for (int i = 1; i <= nrVertices; ++i) {
        weights.push_back(INT_MAX);
    }

    for (int i = 1; i <= nrEdges; ++i) {
        myFile >> nodeX >> nodeY >> weight;
        adj[nodeX].push_back(Vertices(nodeY, weight));
    }

    myFile.close();
}

void Dijkstra(Vertices startNode) {
    Vertices currVertex;

    weights[startNode.vertex] = 0;
    Q.push(startNode);

    while (!Q.empty()) {
        currVertex = Q.top();
        Q.pop();

        if (currVertex.weight <= weights[currVertex.vertex]) {
            for (list<Vertices>::iterator it = adj[currVertex.vertex].begin(); it != adj[currVertex.vertex].end(); ++it) {
                if (weights[it->vertex] > weights[currVertex.vertex] + it->weight) {
                    weights[it->vertex] = weights[currVertex.vertex] + it->weight;
                    Q.push(Vertices((it->vertex), weights[it->vertex]));
                }
            }
        }
    }
}

int main() {

    readData();
    Dijkstra(Vertices(1, 0));
    writeData();

    return 0;
}

所以这就是我到目前为止为了实现具有邻接列表的Dijkstra算法。但是,我的代码不会打印任何内容。有什么帮助吗?

Graph.txt看起来像这样:

7
2
2  2
4  1
2
4  3
5  10
2
1  4
6  5
4
3  2
5  2
6  8
7  4
1
7  6
0
1
6  1

这意味着从顶点1到7按顺序存在7个顶点。 顶点1有2个边,一个到顶点2,重量为2,第二个到顶点4,重量为1。 顶点2具有2个边缘,第一个到顶点4具有权重3,第二个到顶点5具有权重10。 顶点3有两条边,第一条到顶点1有重量4,第二条到顶点6有重量5。 等等。

2 个答案:

答案 0 :(得分:0)

此代码:

weights.resize(1);
for (vector<int>::iterator it = weights.begin()+1; it != weights.end(); ++it) {

会将weights向量的大小调整为1,然后尝试打印出向量的第二个元素。由于不再有第二个元素,它不会打印任何东西。

答案 1 :(得分:0)

#include <iostream>
#include <fstream>
#include <functional>
#include <climits>
#include <vector>
#include <queue>
#include <list>

using namespace std;

struct Vertices {
    int vertex;
    int weight;
    Vertices(int v, int w) : vertex(v), weight(w) { };
    Vertices() { }
};

class CompareGreater {
    public:
        bool const operator()(Vertices &nodeX, Vertices &nodeY) {
            return (nodeX.weight > nodeY.weight) ;
        }
};

vector< list<Vertices> > adj;
vector<int> weights;
priority_queue<Vertices, vector<Vertices>, CompareGreater> Q;

int nrVertices, nrEdges;

void readData();
void Dijkstra(Vertices);


void readData() {
    ifstream myFile;
    myFile.open("graph.txt");

    int nodeX, nodeY, weight;

    myFile >> nrVertices >> nrEdges;

    adj.resize(nrVertices+1);
    //weights.resize(1);

    for (int i = 1; i <= nrVertices; ++i) {
        weights.push_back(INT_MAX);
    }

    for (int i = 1; i <= nrEdges; ++i) {
        myFile >> nodeX >> nodeY >> weight;
        adj[nodeX].push_back(Vertices(nodeY, weight));
    }

    //weights.resize(1);
    for (vector<int>::iterator itr = weights.begin()+1; itr != weights.end(); ++itr) {
        cout << (*itr) << " "<<endl;
    }


    myFile.close();
}

void Dijkstra(Vertices startNode) {
    Vertices currVertex;

    weights[startNode.vertex] = 0;
    Q.push(startNode);

    while (!Q.empty()) {
        currVertex = Q.top();
        Q.pop();

        //cout<<"Removed "<<&currVertex<<"from heap"<<endl;

        if (currVertex.weight <= weights[currVertex.vertex]) {
            for (list<Vertices>::iterator it = adj[currVertex.vertex].begin(); it != adj[currVertex.vertex].end(); ++it) {
                if (weights[it->vertex] > weights[currVertex.vertex] + it->weight) {
                    weights[it->vertex] = weights[currVertex.vertex] + it->weight;
                    Q.push(Vertices((it->vertex), weights[it->vertex]));
                }
            }
        }
    }
}

int main() {

    readData();
    Dijkstra(Vertices(1, 0));

    return 0;
}

所以这是我修改后的答案。但它打印出来:

2147483647 
2147483647 
2147483647 
2147483647 
2147483647 
2147483647 

当我需要它打印出这样的东西时:

V1: V2, 2; V4, 1
V2: v4, 3; V5, 10
V3: V1, 4; V6, 5
V4: V3, 2; V5, 2; V6, 8; V7, 4
V5: V7, 6
V6:
V7: V6, 1
Removed minimum 1 from heap
Print heap: V2, d=inf V4., d=inf v3, d= inf v7, d=inf v5......