Cod sursa(job #3128073)

Utilizator Alexander444Alex Chiriac Alexander444 Data 8 mai 2023 15:31:14
Problema Distante Scor 60
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.85 kb
#include <fstream>
#include <vector>
#define NMAX 60000

using namespace std;

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

class Task {
public:
    void solve() {
        read_input();
        print_output(dijkstra());
    }

private:
    int n, m;
    vector<pair<int, int64_t>> adj[NMAX];
    vector<int64_t> distBronz;
    int source;

    void read_input() {
        f >> n >> m >> source;
        distBronz.push_back(-1); // indexing from 1
        for (int i = 1, d; i <= n; ++i)
            f >> d, distBronz.push_back(d);
        int64_t w;
        for (int i = 1, x, y; i <= m; i++) {
            f >> x >> y >> w;
            adj[x].push_back({y, w});
            adj[y].push_back({x, w});
        }
    }


    #define popMin(heap, heapLen, dist, poz) pop(heap, heapLen, dist, poz, 1)
    int pop(vector<int> &heap,int &heapLen,vector<int64_t> &dist,vector<int> &poz,int nod)
    {
        int ret = heap[nod], last = heap[heapLen--];
        while (2 * nod <= heapLen)
            if (dist[last] > dist[heap[2 * nod]])
                heap[nod] = heap[2 * nod], poz[heap[nod]] = nod, nod *= 2;
            else if (2 * nod + 1 <= heapLen && dist[last] > dist[heap[2 * nod + 1]])
                heap[nod] = heap[2 * nod + 1], poz[heap[nod]] = nod, nod = 2 * nod + 1;
            else break;
        heap[nod] = last;
        poz[last] = nod;
        poz[ret] = -1;
        return ret;
    }

    void update(vector<int> &heap, int &heapLen, vector<int64_t> &dist, vector<int> &poz, int nod)
    {
        int last = heap[nod];
        while (nod > 1)
            if (dist[last] < dist[heap[nod / 2]])
                heap[nod] = heap[nod / 2], poz[heap[nod]] = nod,nod /= 2;
            else break;
        heap[nod] = last;
        poz[last] = nod;
    }

    bool dijkstra() {
        vector<int64_t> d(n + 1, -1);
        vector<int> p(n + 1, -1);
        vector<int> heap(n + 1);
        int heapLen=1;
        heap[heapLen]=source;
        p[source]=heapLen;
        d[source]=0;

        while (heapLen) {
            int node = popMin(heap, heapLen, d, p);
            for(auto& [neigh, w] : adj[node])
                if(d[neigh] == -1 || d[neigh] > d[node] + w)
                {
                    d[neigh] = d[node] + w;
                    if (d[neigh] < distBronz[neigh])
                        return false;
                    if (p[neigh] == -1)
                    {
                        heap[++heapLen] = neigh;
                        p[neigh] = heapLen;
                    }
                    update(heap, heapLen, d, p, p[neigh]);
                }
        }
        return true;
    }

    void print_output(bool ok) {
        g << (ok?"DA":"NU") << '\n';
    }
};


int main() {
    int T;

    f >> T;

    for (int i = 0; i < T; ++i) {
        auto* task = new (nothrow) Task();
        task->solve();
        delete task;
    }

    f.close();
    g.close();
}