Cod sursa(job #3176594)

Utilizator tudorcioc5Cioc Tudor tudorcioc5 Data 27 noiembrie 2023 13:20:59
Problema A+B Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.66 kb
// https://www.infoarena.ro/problema/camionas

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

using namespace std;

struct Neighbour
{
    int vertex, cost;
};

// Possible edges to add in the APM
struct APMEdge
{
    int apmVertex, outsideVertex, cost;
};

class Graph
{
private:
    struct CompareCost
    {
        bool operator()(const APMEdge &a, const APMEdge &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;

    vector<int> parent;
    priority_queue<APMEdge, vector<APMEdge>, CompareCost> costToAPM;
    // cost to the APM

    vector<int> costToNode;
    // costul de la nodul 1 la celelalte noduri

public:
    Graph(int noVertices, int noEdges)
        : noVertices(noVertices), noEdges(noEdges),
          neighbours(noVertices + 1),
          parent(noVertices + 1, -1),
          costToNode(noVertices + 1, INT_MAX)
    {
    }

    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});
    }

    int calculateAPM()
    {
        int costToReturn = 0;

        parent[1] = 0;
        costToNode[1] = 0;

        for (Neighbour neigh : neighbours[1])
            costToAPM.push(APMEdge{1, neigh.vertex, neigh.cost});

        // Avand toate muchiile care leaga nodurile din afara APM-ului cu nodurile din interiorul APM-ului
        // in priority_queue, luam muchia cu costul minim (priority_queue.top),
        // o adaugam in APM impreuna cu nodul, iar apoi, pentru "nodul nou adaugat"
        // adaugam toate muchiile care il conecteaza cu noduri din afara APM-ului

        while (!costToAPM.empty())
        {
            APMEdge currEdge = costToAPM.top();
            costToAPM.pop();

            if (parent[currEdge.outsideVertex] != -1)
            {
                continue;
            }

            costToReturn = costToReturn + currEdge.cost;

            parent[currEdge.outsideVertex] = currEdge.apmVertex;

            for (Neighbour neigh : neighbours[currEdge.outsideVertex])
            {
                if (parent[neigh.vertex] == -1)
                    costToAPM.push({currEdge.outsideVertex, neigh.vertex, neigh.cost});

                if (costToNode[currEdge.apmVertex] + currEdge.cost < costToNode[currEdge.outsideVertex])
                    costToNode[currEdge.outsideVertex] = costToNode[currEdge.apmVertex] + currEdge.cost;
            }
        }

        return costToNode[noVertices];
    }

    vector<int> &getParentArray()
    {
        return parent;
    }
};

int main()
{
    int N, M, G;

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

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

        graph.addNeighbours(left, right, cost < G);
    }

    fin.close();

    vector<int> result;
    int cost = graph.calculateAPM();

    result = graph.getParentArray();

    ofstream fout("camionas.out");
    fout << cost << "\n";
    fout.close();

    return 0;
}