Cod sursa(job #3304481)

Utilizator robigiirimias robert robigi Data 24 iulie 2025 00:49:38
Problema Algoritmul lui Dijkstra Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.73 kb
#include <fstream>
#include <vector>
#include <algorithm>
#include <functional>

using namespace std;

const int INF = 1e9;

struct Node
{
    int v, d;
    Node* next;
    Node(int v, int d, Node* next = nullptr) : v(v), d(d), next(next) {}
};

auto cmp = [](auto& a, auto& b) {
    return a.first > b.first; // Min-heap based on distance
    };


void upheap(int id, std::vector<pair<int, int>>& heap, std::vector<int>& inheap)
{
    while (id > 1)
    {
        int parent = id / 2;
        if (cmp(heap[parent], heap[id]))
        {
            std::swap(heap[id], heap[parent]);
            inheap[heap[id].second] = id;
            inheap[heap[parent].second] = parent;
            id = parent;
        }
        else
        {
            return;
        }
    }
}

void downheap(int id, std::vector<pair<int, int>>& heap, std::vector<int>& inheap)
{
    int n = heap.size() - 1;
    while (id * 2 <= n)
    {
        int left_child = id * 2;
        int right_child = id * 2 + 1;
        int smallest = id;
        if (left_child <= n && cmp(heap[smallest], heap[left_child]))
        {
            smallest = left_child;
        }
        if (right_child <= n && cmp(heap[smallest], heap[right_child]))
        {
            smallest = right_child;
        }
        if (smallest != id)
        {
            std::swap(heap[id], heap[smallest]);
            inheap[heap[id].second] = id;
            inheap[heap[smallest].second] = smallest;
            id = smallest;
        }
        else
        {
            return;
        }
    }
}

pair<int, int> removeMin(vector<pair<int, int>>& heap, vector<int>& inheap)
{
    std::pair<int, int> minElement = heap[1];
    inheap[minElement.second] = -1; // Mark as removed
    heap[1] = heap.back();
    heap.pop_back();
    if (!heap.empty())
    {
        inheap[heap[1].second] = 1;
        downheap(1, heap, inheap);
    }
    return minElement;
}

std::vector<int> dijkstra(int start, int n, vector<Node*>& graph)
{
    std::vector<pair<int, int>> heap(n + 1, { INF, -1 });
    vector<int> inheap(n + 1, -1);
    for (int i = 1; i <= n; ++i)
    {
        heap[i].first = INF;
        heap[i].second = i;
    }

    std::make_heap(heap.begin() + 1, heap.end(), cmp);

    for (int i = 1; i <= n; ++i)
    {
        inheap[heap[i].second] = i;
    }

    int id = inheap[start];
    heap[id].first = 0;

    upheap(id, heap, inheap);

    vector<int> dist;
    dist.resize(n + 1, INF);
    dist[start] = 0;

    for (int i = 1; i < n; ++i)
    {
        if (heap.size() <= 1)
            break;

        auto minElement = removeMin(heap, inheap);
        int u = minElement.second;
        int d = minElement.first;

        if (d == INF)
            break;

        Node* current = graph[u];
        while (current != nullptr)
        {
            int v = current->v;
            int w = current->d;
            if (dist[v] > dist[u] + w)
            {
                dist[v] = dist[u] + w;
                heap[inheap[v]].first = dist[v];
                upheap(inheap[v], heap, inheap);
            }
            current = current->next;
        }
    }
    return dist;
}

int main()
{
    ifstream fin("dijkstra.in");
    ofstream fout("dijkstra.out");

    int n, m;
    fin >> n >> m;

    vector<Node*> graph(n + 1, nullptr);

    for (int i = 0; i < m; ++i)
    {
        int u, v, d;
        fin >> u >> v >> d;
        graph[u] = new Node(v, d, graph[u]);
    }

    vector<int> dist = dijkstra(1, n, graph);

    for (int i = 2; i <= n; ++i)
    {
        if (dist[i] == INF)
            fout << "INF\n";
        else
            fout << dist[i] << " ";
    }
    return 0;
}