Cod sursa(job #2822792)

Utilizator blxqnAlina Voiculescu blxqn Data 25 decembrie 2021 16:32:17
Problema Distante Scor 50
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.59 kb
#include <bits/stdc++.h>
using namespace std;

ifstream fin("distante.in");
ofstream fout("distante.out");

const int INF = 0x3f3f3f3f;
const int MAX = 50001; //500000 eulerian cycle
                      //100000 apm, tree diameter

class Graph
{
///PRIVATE
    int numberOfNodes;
    int numberOfEdges;
    bool directed;
    bool fromOne;  //if first node is 1 => true

    vector<vector<int>> adjacencyList;
    vector<pair<int, int>> adjacencyListWeightedGraph[MAX];
    vector<vector<int>> adjacencyMatrixWeightedGraph;
    vector<pair<int,int>> adjacencyListWithEdgesNumber[MAX];

///PUBLIC
    public:
        Graph();
        Graph(int, int, bool, bool);
        Graph(int, bool, bool);

        ~Graph() { }

        void Build(istream&);
        void BuildFromVector(vector<vector<int>>);
        void BuildWeightedGraph(istream&);
        void BuildAdjacencyMatrixWeightedGraph(istream&);
        void BuildGraphWithEdgesNumber(istream&);
        void BuildTransposeWeightedGraph(istream&);

        int GetNumberOfNodes();
        int GetNumberOfEdges();
        bool IsDirected();
        bool IsFromOne();

        vector<int> Dijkstra(int);

        void Reset();
};

int main()
{
    int numberOfGraphs;
    fin >> numberOfGraphs;

    for (int i = 1; i <= numberOfGraphs; i++)
    {
        int numberOfNodes, numberOfEdges, startNode;
        bool OK = 1;
        fin >> numberOfNodes >> numberOfEdges >> startNode;

        vector<int> solutionBronzarel(numberOfNodes + 1, 0);

        for (int i = 1; i <= numberOfNodes; i++)
            fin >> solutionBronzarel[i];

        Graph G(numberOfNodes, numberOfEdges, 0, 0);
        G.BuildWeightedGraph(fin);

        vector<int> key = G.Dijkstra(startNode);

        for (int i = 1; i <= numberOfNodes; i++)
        {
            if (key[i] == INF)
                key[i] = 0;

            if (key[i] != solutionBronzarel[i])
            {
                OK = 0;
                break;
            }
        }

        G.Reset();

        if (OK)
            fout << "DA\n";
        else
            fout<<"NU\n";
    }

    fin.close();
    fout.close();

    return 0;
}

Graph::Graph() : numberOfNodes(0), numberOfEdges(0), directed(0), fromOne(0) { }

Graph::Graph(int _numberOfNodes, int _numberOfEdges, bool _directed, bool _fromOne) : numberOfNodes(_numberOfNodes), numberOfEdges(_numberOfEdges), directed(_directed), fromOne(_fromOne)
{
    for (int i = 0; i < _numberOfNodes; i++)
        adjacencyList.push_back( {} );
        //adjacencyList.push_back(vector<int>());
}

Graph::Graph(int _numberOfNodes, bool _directed, bool _fromOne) : numberOfNodes(_numberOfNodes), numberOfEdges(INF), directed(_directed), fromOne(_fromOne)
{
    for (int i = 0; i < _numberOfNodes; i++)
        adjacencyMatrixWeightedGraph.push_back( {} );
        //adjacencyMatrixWeightedGraph.push_back(vector<int>());
}

void Graph::BuildWeightedGraph(istream &fin)
{
    for (int i = 1; i <= numberOfEdges; i++)
    {
        int firstNode, secondNode, weight;
        fin >> firstNode >> secondNode >> weight;

        if (fromOne)
        {
            firstNode--;
            secondNode--;
        }

        adjacencyListWeightedGraph[firstNode].push_back(make_pair(secondNode, weight));

        if (!directed)
            adjacencyListWeightedGraph[secondNode].push_back(make_pair(firstNode, weight));
    }
}

vector<int> Graph::Dijkstra(int startNode)
{
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> minHeap;
    vector<int> key;
    vector<bool> inDijkstra(numberOfNodes + 1, 0);

    key.clear();
    key.resize(numberOfNodes + 1);

    for (int i = 1; i <= numberOfNodes; i++)
        key[i] = INF;

    minHeap.push(make_pair(0, startNode));
    key[startNode] = 0;

    while(!minHeap.empty())
    {
        int node = minHeap.top().second;
        minHeap.pop();

        if(inDijkstra[node] == 1)
            continue;
        else
            inDijkstra[node] = 1;

        for (auto i : adjacencyListWeightedGraph[node])
        {
            int adjacentNode = i.first;
            int adjacentNodeWeight = i.second;

            if (key[node] + adjacentNodeWeight < key[adjacentNode])
            {
                key[adjacentNode] = key[node] + adjacentNodeWeight;
                minHeap.push(make_pair(key[adjacentNode], adjacentNode));
            }
        }
    }

    return key;
}

void Graph::Reset()
{
    for (int i = 1; i <= numberOfNodes; i++)
        adjacencyListWeightedGraph[i].clear();
}