Cod sursa(job #2277288)

Utilizator ShootingHorseHorsie Horse ShootingHorse Data 5 noiembrie 2018 23:01:06
Problema Distante Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.61 kb
#include <fstream>
#include <vector>
#include <string.h>

using namespace std;

#define MAX_NODES       50001

class Heap {
    int add_index, max_size, *heap, *pos;
    const int *key;

    void heap_swap(int id1, int id2) {
        pos[heap[id1]] ^= pos[heap[id2]];
        pos[heap[id2]] ^= pos[heap[id1]];
        pos[heap[id1]] ^= pos[heap[id2]];

        heap[id1] ^= heap[id2];
        heap[id2] ^= heap[id1];
        heap[id1] ^= heap[id2];
    }

    void upheap(int index) {
        while (index > 1 && key[index] < key[index >> 1]) {
            heap_swap(index, index >> 1);
            index >>= 1;
        }
    }

    void downheap(int index) {
        int id1, id2, min_child_id;

        while (index < add_index) {
            id1 = index << 1;
            id2 = id1 + 1;


            if (id1 >= add_index)
                break;
            if (id2 >= add_index)
                min_child_id = id1;
            else
                min_child_id = key[heap[id1]] < key[heap[id2]] ? id1 : id2;

            if (key[heap[index]] > key[heap[min_child_id]])
                heap_swap(index, min_child_id);
            else
                break;

            index = min_child_id;
        }
    }

public:
    Heap(int max_size, const int *key) : max_size(max_size),
                                         add_index(1), 
                                         heap(new int[max_size]),
                                         pos(new int[max_size]),
                                         key(key) {
                                            //memset(pos, 0, max_size * sizeof(int));
                                         }

    ~Heap() {
        delete [] heap;
        delete [] pos;
    }

    void add(int x) {
        heap[add_index] = x;
        pos[x] = add_index;

        upheap(add_index);
        add_index++;
    }

    int top() {
        int top = heap[1];
        heap_swap(1, --add_index);
        pos[top] = 0;
        
        downheap(1);

        return top;
    }

    void heapify_elem(int node) {
        int index = pos[node];

        if (index != 1 && key[index] < key[index >> 1])
            upheap(pos[node]);
        else
            downheap(index);
    }

    bool has_element(int x) {
        return pos[x];
    }

    int size() {
        return (add_index - 1);
    }
};

void dijkstra(vector<pair<int, int> > *graph, Heap &heap, int source, int *sol)
{
    Heap heap(MAX_NODES, sol);

    heap.add(source);
    sol[source] = 0;
    while(heap.size()) {
        int node = heap.top();

        for (const auto &i : graph[node]) {
            if (sol[i.first] == -1 || (sol[node] + i.second < sol[i.first])) {
                sol[i.first] = sol[node] + i.second;

                if (heap.has_element(i.first))
                    heap.heapify_elem(i.first);
                else
                    heap.add(i.first);
            }
        }
    }

    return;
}

int main()
{
    ifstream in("distante.in");
    ofstream out("distante.out");

    int sol[MAX_NODES];

    int t;
    in >> t;
    while(t--) {
        vector<pair<int, int> > graph[MAX_NODES];
        int maybe_sol[MAX_NODES];
        int n, m, s, x, y, w;
        in >> n >> m >> s;

        memset(sol, -1, (n + 1) * sizeof(int));

        for (int i = 1; i <= n; i++)
            in >> maybe_sol[i];

        for (int i = 1; i <= m; i++) {
            in >> x >> y >> w;
            graph[x].push_back(make_pair(y, w));
            graph[y].push_back(make_pair(x, w));
        }

        dijkstra(graph, heap, s, sol);

        if (memcmp(sol + 1, maybe_sol + 1, sizeof(int) * n))
            out << "NU\n";
        else
            out << "DA\n";
    }

    return 0;
}