Cod sursa(job #1708353)

Utilizator Irina96Dumea Irina Irina96 Data 26 mai 2016 22:15:57
Problema Algoritmul lui Dijkstra Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 2.94 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>

using namespace std;

class muchie
{
    unsigned nod1, nod2;
    unsigned cost;
public:
    bool operator < (muchie m) {return cost>m.cost;};
    friend class Graf;
};

class Graf
{
    unsigned N;
    unsigned long M;
    struct semi {unsigned nod; unsigned cost; semi *urm;};
    unsigned long distanta[50001];
    semi * G[50001];
    void push (unsigned unde, unsigned nod, unsigned C);
public:
    Graf ();
    void citire();
    void dijkstra (unsigned start);
    void aff();
    ~Graf ();
};

void Graf::dijkstra (unsigned start)
{
    unsigned i, curent=start, cost, adiacent;
    for (i=1; i<=N; i++)
        distanta[i]=500000000;
    distanta[start]=0;
    vector<muchie> HEAP;
    muchie mch;
    do
    {
        //in "curent" avem ultimul nod ales
        semi *aux;
        cost=distanta[curent];
        for (aux=G[curent]; aux!=NULL; aux=aux->urm)
        {
            if (cost+aux->cost < distanta[aux->nod])
            {
                mch.cost=aux->cost;
                mch.nod1=curent;
                mch.nod2=aux->nod;
                HEAP.push_back(mch);
                push_heap(HEAP.begin(), HEAP.end());
            }
        }
        //am adaugat toate muchiile noi puse de nodul curent
        //trebuie sa alegem urmatorul nod pe care il updatam
        while (!HEAP.empty() && HEAP[0].cost + distanta [HEAP[0].nod1] >= distanta[HEAP[0].nod2])
        {
            pop_heap(HEAP.begin(), HEAP.end());
            HEAP.pop_back();
        }
        //acum alegand muchia HEAP[0] se updateaza urmatorul nod
        if (!HEAP.empty())
        {
            curent=HEAP[0].nod2;
            adiacent=HEAP[0].nod1;
            distanta[curent]=HEAP[0].cost+distanta[adiacent];
            pop_heap(HEAP.begin(), HEAP.end());
            HEAP.pop_back();
        }
    }
    while (!HEAP.empty());
    HEAP.clear();
    for (i=2; i<=N; i++)
        if (distanta[i]==500000000)
        distanta[i]=0;
}

void Graf::aff()
{
    unsigned i;
    ofstream f ("dijkstra.out");
    for (i=2; i<=N; i++)
        f<<distanta[i]<<' ';
}

Graf::Graf ()
{
    unsigned i;
    for (i=1; i<=50000; i++)
        G[i]=NULL;
}

Graf::~Graf()
{
    unsigned i;
    semi *aux;
    for (i=1; i<=N; i++)
    {
        while (G[i]!=NULL)
        {
            aux=G[i]->urm;
            delete G[i];
            G[i]=aux;
        }
    }
}

void Graf::push(unsigned unde, unsigned nod, unsigned C)
{
    semi *s;
    s=new semi;
    s->cost=C;
    s->nod=nod;
    s->urm=G[unde];
    G[unde]=s;
}

void Graf::citire()
{
    ifstream f ("dijkstra.in");
    f>>N>>M;
    unsigned long i;
    unsigned x, c, y;
    for(i=0; i<M; i++)
    {
        f>>x>>y>>c;
        push (x, y, c);
    }
}

int main()
{
    Graf G;
    G.citire();
    G.dijkstra(1);
    G.aff();
    return 0;
}