Hi! Please, adjust my program for the given task. You have to implement Djikstra algorithm using Priority queue which is implemented using binary heap. You are not allowed to use additional libraries. 
Task:
Given an oriented graph, determine if it has a cycle of negative weight and print it (if exists).

Input
Input's first line has number N (1 ≤ N ≤ 100) — number of vertices in the graph. Each of the next N lines contains N numbers — all representing an adjacency matrix. All weights are strictly less than 10000 by absolute value. If there is no edge, corresponding value will be exactly 100000.

Output
First line should YES if there exists a negative cycle, or NO otherwise. If the cycle exists, second line should should contain the number of vertices in that cycle and third line should contain indices of those vertices (in cycle order).

Example
inputCopy
2
0 -1
-1 0
outputCopy
YES
2
2 1 
Program to be adjusted:
#include <iostream>
#include <vector>
#include <list>

template<typename T, typename V>
class Edge;
 
template<typename T, typename V>
class Vertex {
    private:
        T label;
        bool visited;
        std::list<Edge<T, V>*> adjacentList;
    public:
        Vertex(T _label) : label(_label), visited(false) {}
        int getDegree() const { return this->adjacentList.size(); }
        T getLabel() const { return this->label; }
        void addEdge(Edge<T, V>* edge) { this->adjacentList.push_back(edge); }
        const std::list<Edge<T, V>*>& getAdjacentList() const { return this->adjacentList; }
        bool isVisited() const { return this->visited; }
        void setVisited(bool visited) { this->visited = visited; }
};
 
template<typename T, typename V>
class Edge {
    private:
        Vertex<T, V>& sVertex;
        Vertex<T, V>& dVertex;
        V weight;
        bool visited;
    public:
        Edge(Vertex<T, V>& _sVertex, Vertex<T, V>& _dVertex, V _weight) : sVertex(_sVertex), dVertex(_dVertex), weight(_weight), visited(false) {}
        const Vertex<T, V>& getAdjacentVertex(const Vertex<T, V>& vertex) const {
            return (vertex.getLabel() != sVertex.getLabel()) ? sVertex : dVertex;
        }
        bool operator>(const Edge<T, V>& other) const { return this->weight > other.weight; }
        T getLabelSource() const { return sVertex.getLabel(); }
        T getLabelDest() const { return dVertex.getLabel(); }
        V getWeight() const { return this->weight; }
        bool isVisited() const { return this->visited; }
        void setVisited(bool val) { this->visited = val; }
    };
 
template<typename T, typename V>
class Graph : public virtual iDisjointSet<T> {
    private:
        int numOfVertices;
        std::list<Vertex<T, V>*> vertices;
        std::list<Edge<T, V>*> edges;
        std::list<std::list<Edge<T, V>*>> trees;
        std::list<int> degrees;
        std::vector<int> parents;
        int singleVertices;
 
        void depthFirstSearch(Vertex<T, V>* vertex, std::list<Edge<T, V>*>& tree) {
            vertex->setVisited(true);
            const std::list<Edge<T, V>*>& adjEdges = vertex->getAdjacentList();
            for (Edge<T, V>* adjEdge : adjEdges) {
                Vertex<T, V>* adjacentVertex = const_cast<Vertex<T, V>*>(&adjEdge->getAdjacentVertex(*vertex));
                if (!adjEdge->isVisited()) { tree.push_back(adjEdge); }
                adjEdge->setVisited(true);
                if (!adjacentVertex->isVisited()) { 
                    depthFirstSearch(adjacentVertex, tree); 
                }
            }
        }
 
        void getTrees() {
            for (Vertex<T, V>* vertex : vertices) {
                if (!vertex->isVisited()) {
                    std::list<Edge<T, V>*> tree;
                    depthFirstSearch(vertex, tree);
                    if (!tree.empty()) {
                        trees.push_back(tree);
                    }
                }
            }
        }
 
        void sortEdges(std::list<Edge<T,V>*>& edges) {
            if (edges.empty()) { return; }
            V minWeight = std::numeric_limits<V>::max();
            V maxWeight = std::numeric_limits<V>::min();
            for (auto edge : edges) {
                minWeight = std::min(minWeight, edge->getWeight());
                maxWeight = std::max(maxWeight, edge->getWeight());
            }
            std::vector<int> count(maxWeight - minWeight + 1, 0);
            for (Edge<T,V>* edge : edges) { count[edge->getWeight() - minWeight]++; }
            for (int i = 1; i < count.size(); i++)
                count[i] += count[i - 1];
            std::vector<Edge<T,V>*> sortedEdges(edges.size());
            for (auto it = edges.rbegin(); it != edges.rend(); ++it) {
                sortedEdges[count[(*it)->getWeight() - minWeight] - 1] = *it;
                count[(*it)->getWeight() - minWeight]--;
            }
            edges.clear();
            for (Edge<T,V>* edge : sortedEdges) { edges.push_back(edge); }
        }
 
 
        std::list<Edge<T, V>*> getMinimumSpanningTree(std::list<Edge<T, V>*>& listOfEdges) {
                std::list<Edge<T, V>*> minimumSpanningTree;
                sortEdges(listOfEdges);
                for (Edge<T, V>* edge : listOfEdges) {
                    int setStart = find(edge->getLabelSource());
                    int setEnd = find(edge->getLabelDest());
                    if (setStart != setEnd) {
                        makeUnion(setStart, setEnd);
                        minimumSpanningTree.push_back(edge);
                    }
                }
                return minimumSpanningTree;
            }
 
        T find(int index) {
            if (this->parents[index] == 0) { return index; }
            this->parents[index] = find(this->parents[index]);
            return this->parents[index];
        }
 
        void makeUnion(int indexStart, int indexEnd) { this->parents[find(indexStart)] = find(indexEnd); }
 
        T getNumberOfVertices(std::list<Edge<T, V>*>& tree) {
            std::vector<T> labels(100000, 0);
            for (Edge<T, V>* edge : tree) {
                T v1 = edge->getLabelSource();
                T v2 = edge->getLabelDest();
                labels[v1] = 1;
                labels[v2] = 1;
            }
            T sum = 0; 
            for (auto i : labels) { sum += i; }
            return sum;
        }
 
        void buildMinimumSpanningForest() {
                getTrees();
                std::cout << this->trees.size() + this->singleVertices << std::endl;
                for (std::list<Edge<T, V>*>& tree : trees) {
                    Edge<T, V>* firstEdge = *tree.begin();
                    std::cout << getNumberOfVertices(tree) << ' ' << firstEdge->getLabelDest() << std::endl;
                    std::list<Edge<T, V>*> mst = getMinimumSpanningTree(tree);
                    for (Edge<T, V>* edge : mst) { 
                        if (edge != nullptr)
                        std::cout << edge->getLabelSource() << " " << edge->getLabelDest() << " " << edge->getWeight() << std::endl;
                    }
                }
            }
 
    public:
        Graph(int _numOfVertices) : numOfVertices(_numOfVertices) { this->parents.resize(100000); this->singleVertices = 0; }
        Graph() = default;
 
        std::list<std::list<Edge<T, V>*>>& decomposeGraph() {
            getTrees();
            return this->trees;
        }
 
        Vertex<T, V>* addVertex(T label) {
            Vertex<T, V>* newVertex = new Vertex<T, V>(label);
            vertices.push_back(newVertex);
            return newVertex;
        }
 
        Edge<T, V>* addEdge(Vertex<T, V>& sVertex, Vertex<T, V>& dVertex, V weight) {
            Edge<T, V>* newEdge = new Edge<T, V>(sVertex, dVertex, weight);
            edges.push_back(newEdge);
            sVertex.addEdge(newEdge);
            dVertex.addEdge(newEdge);
            return newEdge;
        }
 
        void minimumSpanningForest() {
            buildMinimumSpanningForest();
        }
 
        void addSingleVertex() { this->singleVertices++; }
};


int main(void) {
    int numOfVertices, temp;
    const int LIMIT = 100000;
    std::cin >> numOfVertices;
    Graph<int, int> graph(numOfVertices);
    for (int i = 0; i < numOfVertices; i++) {
        for (int j = 0; j < numOfVertices; j++) {
            std::cin >> temp;
            if (temp != 0) {
                Vertex<int, int>* v1 = graph.addVertex(i + 1);
                Vertex<int, int>* v2 = graph.addVertex(j + 1);
                graph.addEdge(*v1, *v2, temp);
            }
        }
    }
    return 0;
}