Cod sursa(job #2228750)

Utilizator Mihai145Oprea Mihai Adrian Mihai145 Data 4 august 2018 17:44:32
Problema Algoritmul lui Dijkstra Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.28 kb
#include <fstream>
#include <vector>

using namespace std;

const int oo = 1000000005;
const int N = 50005;

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

int nodes, startNode, heapSize;
int dist[N], inHeap[N];

vector < pair < int, int > > graph[N];

struct minHeap{
    int node, lenght;
}heap[N];

int ExtractMin()
{
    int returnNode = heap[1].node;
    int lastNode = heap[heapSize].node;
    dist[returnNode] = heap[1].lenght;
    swap(heap[1], heap[heapSize]);
    swap(inHeap[returnNode], inHeap[lastNode]);
    inHeap[returnNode] = -1;
    heapSize--;

    int currentIndex = 1, currentNode = lastNode, currentLenght = heap[1].lenght;

    while(currentIndex * 2 <= heapSize)
    {
        int LChildNode = heap[currentIndex * 2].node;
        int LChildLenght = heap[currentIndex * 2].lenght;
        int nextIndex = currentIndex * 2;

        if(currentIndex * 2 + 1 <= heapSize)
        {
            int RChildNode = heap[currentIndex * 2 + 1].node;
            int RChildLenght = heap[currentIndex * 2 + 1].lenght;

            if(LChildLenght > RChildLenght)
            {
                LChildLenght = RChildLenght;
                LChildNode = RChildNode;
                nextIndex += 1;
            }
        }

        if(LChildLenght < currentLenght)
        {
            swap(inHeap[LChildNode], inHeap[currentNode]);
            swap(heap[currentIndex], heap[nextIndex]);
            currentIndex = nextIndex;
            currentNode = heap[currentIndex].node;
            currentLenght = heap[currentIndex].lenght;
        }
        else
        {
            break;
        }
    }

    return returnNode;
}

void Update(int index, int value)
{
    heap[index].lenght = value;

    int currentIndex = index;
    int currentNode = heap[currentIndex].node;
    int currentLenght = heap[currentIndex].lenght;

    while(currentIndex / 2 >= 1)
    {
        int nextIndex = currentIndex / 2;
        int nextNode = heap[nextIndex].node;
        int nextLenght = heap[nextIndex].lenght;

        if(currentLenght < nextLenght)
        {
            swap(inHeap[currentNode], inHeap[nextNode]);
            swap(heap[currentIndex], heap[nextIndex]);
            currentIndex = nextIndex;
        }
        else
        {
            break;
        }
    }
}

void Dijkstra(int start)
{
    heapSize = nodes;
    for(int i = 1; i <= nodes; i++)
    {
        dist[i] = oo;
        heap[i].node = i;
        heap[i].lenght = oo;
        inHeap[i] = i;
    }
    Update(inHeap[start], 0);

    while(heapSize)
    {
        int currentNode = ExtractMin();

        for(auto it : graph[currentNode])
        {
            int child = it.first;
            int cost = it.second;
            if(inHeap[child] != -1)
            {
                if(dist[currentNode] + cost < heap[inHeap[child]].lenght)
                    Update(inHeap[child], dist[currentNode] + cost);
            }
        }
    }
}

int main()
{
    int x, y, cost;
    fin >> nodes >> startNode;
    while(fin >> x >> y >> cost)
    {
        graph[x].push_back(make_pair(y, cost));
    }

    Dijkstra(1);

    for(int i = 2; i <= nodes; i++)
        fout << ( (dist[i] == oo) ? 0 : dist[i] ) << ' ';

    return 0;
}