Cod sursa(job #2825461)

Utilizator vlad-123-123vlad calomfirescu vlad-123-123 Data 4 ianuarie 2022 19:16:28
Problema Distante Scor 60
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.37 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <climits>
#include <queue>
#include <set>

#define inf 999999

using namespace std;

ifstream f("distante.in");
ofstream g("distante.out");

int n, m, sursa, T;
bool visited[50001];
int value[50001];

vector<pair<int, int> > adj[50001];
// void dijkstra(int start)
// {
//     priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> Q;
//     Q.push(make_pair(0, start));
//     while (Q.empty() == 0)
//     {
//         int nod_curent = Q.top().second;
//         Q.pop();
//         if (visited[nod_curent] == 0)
//         {
//             visited[nod_curent] = 1;
//             for (int i = 0; i < int(adj[nod_curent].size()); i++)
//             {
//                 int vecin = adj[nod_curent][i].first;
//                 if (value[vecin] > value[nod_curent] + adj[nod_curent][i].second)
//                 {
//                     value[vecin] = value[nod_curent] + adj[nod_curent][i].second;
//                     Q.push(make_pair(value[vecin], vecin));
//                 }
//             }
//         }
//     }
// }

void dijkstra1(int sursa)
{
    set<pair<int, int> > set_cost_nod; // set_cost_nod retine nodurile inca neprocesate si costul pt a ajunge in ele
    // folosim set pt ca atunci cand vom lua un alt nod vrem sa il luam pe cel cu costul minim
    //  ce se afla la un mom de timp in set_nod_cost, inseamna ca acele noduri nu au fost inca procesate.
    set_cost_nod.insert(make_pair(0, sursa)); // cost 0 pt nodul sursa 1
    while (!set_cost_nod.empty())
    {
        int nod = (*set_cost_nod.begin()).second; // luam nodul curent
        set_cost_nod.erase(set_cost_nod.begin()); // pop nod crr si cost
        if (visited[nod] == 0)
        {
            visited[nod] = 1;
            for (int i = 0; i < adj[nod].size(); ++i)
            {
                int nod_dest = adj[nod][i].first;             // nod_dest = este nodul destinatie de la care plecam din nodul crr("nod")
                int cost_dest = adj[nod][i].second;           // costul muchiei de la nod la nod_dest
                if (value[nod] + cost_dest < value[nod_dest]) // value[nod] retine dist de la nodul src(1) la nodul crr (nod)
                // adugam costul de la nod crr la nod dest sa vedem daca gasim o cale mai "ieftina" din nodul src(1) la nod dest
                {
                    if (value[nod_dest] != inf)
                    {
                        set_cost_nod.erase(set_cost_nod.find(make_pair(value[nod_dest], nod_dest)));
                        // in cazul in care value[nod_dest] !=inf adica dist din 1 la nod_dest a mai fost actualizata si totusi s-a gasit
                        // un drum mai scurt, vom scoate valoarea veche din set_nod_cost pt a o reactualiza mai jos in value si pt a face push
                        // in set la noua valoare pt nod_dest
                    }
                    // deci se respecta cond din if
                    value[nod_dest] = value[nod] + cost_dest;                  // actualizam noul cost pt nodul dest
                    set_cost_nod.insert(make_pair(value[nod_dest], nod_dest)); // inseram in set (costul de a ajung din src la nod_dest, nod dest)
                    // la urmatoarele iteratii se va lua nod_dest ca fiind noul nod crr
                }
            }
        }
    }
}

int main()
{
    f >> T;
    for (int i = 1; i <= T; i++)
    {
        f >> n >> m >> sursa;
        int bronzanel[n + 1];
        for (int j = 1; j <= n; j++)
        {
            f >> bronzanel[j];
        }
        for (int j = 1; j <= n; j++)
        {
            visited[j] = 0;
        }
        // int val_max=inf;
        for (int j = 1; j <= n; j++)
        {
            value[j] = inf;
        }
        value[sursa] = 0;
        for (int j = 1; j <= m; j++)
        {
            int a, b, c;
            f >> a >> b >> c;
            adj[a].push_back(make_pair(b, c));
            adj[b].push_back(make_pair(a, c));
        }
        dijkstra1(sursa);
        for (int j = 1; j <= n; j++)
        {
            adj[j].erase(adj[j].begin(), adj[j].end());
        }
        bool verif = 1;
        for (int j = 1; j <= n; j++)
        {
            if (value[j] != bronzanel[j])
            {
                verif = 0;
                break;
            }
        }
        if (verif == 1)
        {
            g << "DA\n";
        }
        else
            g << "NU\n";
    }
    return 0;
}