Cod sursa(job #3176707)

Utilizator tudorcioc5Cioc Tudor tudorcioc5 Data 27 noiembrie 2023 17:13:15
Problema Algoritmul lui Dijkstra Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.17 kb
// https://www.infoarena.ro/problema/dijkstra

#include <iostream>
#include <vector>
#include <utility>
#include <climits>
#include <deque>
#include <queue>
#include <fstream>
#include <algorithm>

using namespace std;

struct Neighbour
{
    int vertex, cost;
};

struct DijkstraNeighbour
{
    int vertex, parent, cost; 
};


class Graph
{
private:
    struct CompareCost
    {
        bool operator()(const DijkstraNeighbour &a, const DijkstraNeighbour &b) const
        {
            return a.cost > b.cost;
        }
    };

    static const int MAX_VERTICES = 200000;
    static const int MAX_EDGES = 400000;

    int noVertices;
    int noEdges;

    vector<vector<Neighbour>> neighbours;

public:
    Graph(int noVertices, int noEdges)
        : noVertices(noVertices), noEdges(noEdges),
          neighbours(noVertices + 1)
    {
    }

    int getNoVertices()
    {
        return noVertices;
    }

    int getNoEdges()
    {
        return noEdges;
    }

    void addNeighbours(int vertex1, int vertex2, int cost)
    {
        neighbours[vertex1].push_back({vertex2, cost});
        neighbours[vertex2].push_back({vertex1, cost});
    }

    void addNeighbour(int vertex, int neighbour_to_add, int cost)
    {
        neighbours[vertex].push_back({neighbour_to_add, cost});
    }

    void calculateDijkstra(int startNode, vector<int>& costToSelectedVertex)
    {
        priority_queue<DijkstraNeighbour, vector<DijkstraNeighbour>, CompareCost> vertexQueue;
        // folosim priority queue pentru a gasi cel mai apropiat nod de nodul sursa
        // (nodul cu care am inceput Dijkstra)


        costToSelectedVertex = vector<int>(noVertices + 1, INT_MAX);
        costToSelectedVertex[startNode] = 0;

        for (Neighbour neigh : neighbours[startNode])
            vertexQueue.push(DijkstraNeighbour{neigh.vertex, startNode, neigh.cost});


        while (!vertexQueue.empty())
        {
            DijkstraNeighbour currEdge = vertexQueue.top();
            vertexQueue.pop();

            if (costToSelectedVertex[currEdge.vertex] != INT_MAX)
            {
                continue;
            }

            costToSelectedVertex[currEdge.vertex] = currEdge.cost;
            

            for (Neighbour neigh : neighbours[currEdge.vertex])
                if (costToSelectedVertex[neigh.vertex] == INT_MAX)
                    vertexQueue.push({neigh.vertex, currEdge.vertex, currEdge.cost + neigh.cost});
        }



        for (int i=1; i <= noVertices; i++)
            if (costToSelectedVertex[i] == INT_MAX)
                costToSelectedVertex[i] = 0;
    }
};



int main()
{
    int N, M;

    ifstream fin ("dijkstra.in");
    fin>> N >> M;
    Graph graph(N, M);

    for (int i=1; i<=M; i++)
    {
        int left, right, cost;
        fin >> left >> right >> cost;

        graph.addNeighbour(left, right, cost);
    }
    
    fin.close();


    vector<int> result;
    graph.calculateDijkstra(1, result);

    ofstream fout("dijkstra.out");

    for (int i=2; i <= N; i++)
        fout << result[i] << " ";
    fout << "\n";

    fout.close();

    return 0;
}