Cod sursa(job #1887006)

Utilizator Luncasu_VictorVictor Luncasu Luncasu_Victor Data 21 februarie 2017 12:00:05
Problema Distante Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.24 kb
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cassert>
using namespace std;

#define INF 0x7FFFFFFF
#define MAX_NODES 50050

struct MyPair{
    int key, val;
};

vector<MyPair> g[MAX_NODES];
int t,n,m,s,a,b,c, d[MAX_NODES];

class Heap{
public:
    Heap(int n) {
        for (int i = 1; i <= n; ++i) {
            pos[i] = -1;
        }
    }
    void push(int key, int val) {
        if (pos[key] == -1) {
            pos[key] = h.size();
            h.push_back({key, val});
        }
        int f = pos[key], t;
        while (f > 0) {
            t = (f - 1) / 2;
            if (h[t].val > h[f].val) {
                swap(h[t], h[f]);
                swap(pos[h[t].key], pos[h[f].key]);
            } else break;
            f = t;
        }
    }
    MyPair top() {
        assert(h.size() > 0);
        return h[0];
    }
    void pop() {
        assert(h.size() > 0);
        pos[h[0].key] = -1;
        h[0] = h.back();
        h.pop_back();
        pos[h[0].key] = 0;
        int t = 0, f = 1;
        while (2 * t + 1 < h.size()) {
            f = 2 * t + 1;
            if (f + 1 < h.size() && h[f + 1].val < h[f].val) f++;
            if (h[f].val < h[t].val) {
                swap(h[t], h[f]);
                swap(pos[h[t].key], pos[h[f].key]);
            } else break;
            t = f;
        }
    }
    int size() {
        return h.size();
    }

private:
    vector<MyPair> h;
    int pos[MAX_NODES];
};

class Dijkstra {
public:
    Dijkstra(int n) : n(n) {
        d.resize(n + 1);
    }

    void dist(int s) {
        for (int i = 1; i <= n; ++i) d[i] = INF;
        d[s] = 0;
        Heap h(n);
        h.push(s, 0);
        while (h.size() > 0) {
            MyPair t = h.top();
            int x = t.key, cost, y;
            h.pop();
            for (int i = 0; i < g[x].size(); ++i) {
                y = g[x][i].key;
                cost = g[x][i].val;
                if (d[y] > d[x] + cost) {
                    d[y] = d[x] + cost;
                    h.push(y, d[y]);
                }
            }
        }
    }

    bool same(int *orig) {
        for (int i = 1; i <= n; ++i) {
            if (d[i] != orig[i]) {
                return false;
            }
        }
        return true;
    }

private:
    int n;
    vector<int> d;
};

int main() {

//    Heap h(4);
//    h.push(1, 10);
//    h.push(2, 20);
//    h.push(3, -5);
//    h.push(3, -100);
//    cout << h.top().val << endl;
//    h.pop();
//    cout << h.top().val << endl;
//    h.pop();
//    cout << h.top().val << endl;

    freopen("distante.in","r",stdin);
    freopen("distante.out", "w", stdout);
    scanf("%d", &t);
    while (t--) {
        scanf("%d %d %d", &n, &m, &s);
        for (int i = 1; i <= n; ++i) {
            scanf("%d", &d[i]);
        }
        memset(g, 0, sizeof(g));
        for (int i = 0; i < m; ++i) {
            scanf("%d %d %d", &a, &b, &c);
            g[a].push_back({b, c});
            g[b].push_back({a, c});
        }
        Dijkstra dij(n);
        dij.dist(s);
//        for (int i = 1; i <= n; ++i) {
//            cout << sol[i] << " ";
//        }
//        cout << endl;
        if (dij.same(d)) {
            cout << "DA" << endl;
        } else {
            cout << "NU" << endl;
        }
    }


    return 0;
}