Dijkstra的邻接列表表示算法+最短路径

时间:2017-04-30 21:43:15

标签: c++ algorithm graph shortest-path dijkstra

我正在编写程序,检查最短的图形补丁,从选定的顶点到目标,我有问题显示补丁。当顶点的类型是' 2'时,顶点有时会有额外的权重(如代码波形变量currentWeight)。所以我在djikstra中添加它。当我将currentWeight设置为10时,它运行良好,但是当我将它设置为2时,它会给我带来不好的结果。例如,输入为:

5 2
4 2 1 1 3 2
2 2 0 1 2 1
5 2 1 1 4 2
0 2 0 2 4 3
0 2 3 3 2 2

前两个数字:v的数量,顶点的附加权重类型' 2'

第二行:顶点类型(4),命运数(2),命运1(1),补丁重量(1),命运2(3),补丁2的权重(2)

输出应为:

0 1 2 

但现在是:

0 3 2 4 

我不知道出了什么问题。这是我的代码:

#include <stdio.h>
#include <iostream>
#include <conio.h>
#include <limits.h>

using namespace std;



struct graphNode {
    int weight;
    int v;
    graphNode *next;
};

class Graph {


public:
    graphNode *head, *tail;
    int size;                   
    int  currentWeight;
    char type;                              



    void addNode(int v_temp, int v_weight) {
        graphNode *temp = new graphNode;
        temp->next = nullptr;

        if (head == nullptr) {
            temp->v = v_temp;
            temp->weight = v_weight;
            head = temp;

        }
        else {
            tail->next = temp;
            temp->v = v_temp;
            temp->weight = v_weight;
        }

        size++;
        tail = temp;
    }


    void setHome(char type, int timeKnight, int timeNi) {

        switch (type) {
        case '0':
            currentWeight = 0;
            break;
        case '1':
            currentWeight = 0;
            break;
        case '2':
            currentWeight = timeKnight;
            break;
        case '3':
            currentWeight = timeNi;
            break;
        case '4':
            currentWeight = 0;
            break;
        case '5':
            currentWeight = 0;
            break;
        }
    }

    void printGraph() {
        graphNode *temp = head;

        if (head != nullptr && tail != nullptr) {
            while (temp) {
                printf("%d(W: %d)  ", temp->v, temp->weight);
                temp = temp->next;
            }
            printf("\n");
        }
    }


    // GET SET METHODS


    char returnType() {
        return type;
    }

    int returnCurrentSize() {
        return currentWeight;
    }


    int returnWeight(graphNode *temp) {
        return temp->weight;
    }


    void setType(char type_temp) {
        type = type_temp;
    }

    // Constructor

    Graph() {
        head = nullptr;
        tail = nullptr;
        size = 0;
        currentWeight = 0;
    }
};


struct heapNode {
    int v;
    int distance;


};



class Heap {
private:
    Graph *graphArray;
    heapNode **heapArray;
    heapNode *root;
    int vNumber, size;
    int *position, *parent;

public:
    heapNode *addEdge(int temp_v, int temp_distance) {

        heapNode *temp = new heapNode;
        temp->v = temp_v;
        temp->distance = temp_distance;

        return temp;
    }


    graphNode *returnVertexHead(int i) {
        return graphArray[i].head;
    }

    char returnType(int i) {
        return graphArray[i].returnType();
    }


    int returnWeight(int i) {
        return graphArray[i].returnCurrentSize();
    }

    bool isInHeap(int temp_v) {
        if (position[temp_v] < vNumber) return true;
        return false;
    }

    bool isEmpty() {
        if (vNumber == 0) return true;

        return false;
    }

    void decrestDistans(int temp_v, int temp_distance) {
        int index = position[temp_v];
        heapNode *temp;

        heapArray[index]->distance = temp_distance;


        while (index > 0 && (heapArray[index]->distance < heapArray[(index - 1) / 2]->distance)) {

            position[heapArray[index]->v] = (index - 1) / 2;
            position[heapArray[(index - 1) / 2]->v] = index;

            temp = heapArray[index];


            heapArray[index] = heapArray[(index - 1) / 2];
            heapArray[(index - 1) / 2] = temp;

            index = (index - 1) / 2;
        }
    }


    heapNode *removeMin() {

        if (vNumber == 0) return nullptr;
        root = heapArray[0];
        heapArray[0] = heapArray[vNumber - 1];


        position[root->v] = vNumber - 1;
        position[heapArray[vNumber - 1]->v] = 0;

        vNumber--;

        repairHeapDown(0);
        return root;
    }

    void repairHeapDown(int index) {
        heapNode *temp;
        int parent = index;
        int left = index * 2 + 1;
        int right = index * 2 + 2;

        if (left <= vNumber && heapArray[parent]->distance > heapArray[left]->distance) parent = left;
        if (right <= vNumber && heapArray[parent]->distance > heapArray[right]->distance) parent = right;
        if (index != parent) {

            position[heapArray[parent]->v] = index;
            position[heapArray[index]->v] = parent;

            temp = heapArray[index];
            heapArray[index] = heapArray[parent];
            heapArray[parent] = temp;


            repairHeapDown(index);
        }
    }



    void djikstra(int v_index) {

        int *distance = new int[vNumber];
        int i, v, weight;
        graphNode *current_graph;
        heapNode *current_heap;

        for (int i = 0; i < vNumber; i++)
        {
            distance[i] = INT_MAX;
            heapArray[i] = addEdge(i, distance[i]);
            position[i] = i;
            parent[i] = 0;

        }
        parent[0] = 0;
        heapArray[v_index] = addEdge(v_index, distance[v_index]);
        position[v_index] = v_index;
        distance[v_index] = 0;

        cout << v_index << " ";

        decrestDistans(v_index, distance[v_index]);


        while (!isEmpty()) {


            current_heap = removeMin();
            i = current_heap->v;


            if (returnType(i) == '5') break;


            current_graph = returnVertexHead(i);

            while (current_graph != nullptr) {

                v = current_graph->v;
                weight = current_graph->weight + returnWeight(v);

                if (isInHeap(v) && distance[i] != INT_MAX && ((weight + distance[i]) < distance[v])) {
                    distance[v] = distance[i] + weight;
                    decrestDistans(v, distance[v]);
                    parent[i] = v;
                }


                current_graph = current_graph->next;
            }


        }

        printHeap(parent, v_index);
    }




    void printHeap(int temp_distance[], int v) {

        for (int i = 0; i < size; i++)
        {
            if (temp_distance[i] != 0)
                cout << temp_distance[i] << " ";

        }
    }



    Heap(Graph *table, int temp_vNumber) {
        vNumber = temp_vNumber;
        size = temp_vNumber;
        root = nullptr;
        heapArray = new heapNode*[temp_vNumber];
        position = new int[temp_vNumber];
        parent = new int[temp_vNumber];
        graphArray = table;
    }
};



int main() {
    int n, time_knight, patch_number, temp_v, temp_weight, i,
        home_index, gral_index, ni_index;
    char type;

    i = 0;


    cin >> n >> time_knight;
    Graph *table = new Graph[n];

    while (1) {
        cin >> type;


        table[i].setType(type);
        table[i].setHome(type, time_knight, 0);

        if (type == '4') home_index = i;
        if (type == '5') gral_index = i;
        if (type == '3') ni_index = i;

        cin >> patch_number;
        for (int j = 0; j < patch_number; j++)
        {
            cin >> temp_v >> temp_weight;
            table[i].addNode(temp_v, temp_weight);

        }

        i++;

        if (i == n) break;
    }

    Heap *object = new Heap(table, n);

    object->djikstra(home_index);


    _getch();

    return 0;
}

0 个答案:

没有答案