Cod sursa(job #1114038)

Utilizator Daniel3717Aleca Daniel Adrian Daniel3717 Data 21 februarie 2014 10:52:56
Problema Algoritmul lui Dijkstra Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 4.29 kb
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

#define inf 2000000000
struct sheap
{
    int val,node;
};

bool operator < (sheap a,sheap b)
{
    if (a.val<b.val)
        return true;
    return false;
}

//must do
void init(vector <sheap> &heap)
{
    sheap ax;
    ax.val=-inf;
    ax.node=-1;
    heap.push_back(ax);
}

bool safe(vector <sheap> &heap,int pos)
{
    if (pos>=heap.size())
        return false;
    if (pos<=0)
        return false;
    return true;
}

void heapswap(vector <sheap> &heap,vector <int> &vpos,int pos1,int pos2)
{
    sheap ax;
    ax=heap[pos1];
    heap[pos1]=heap[pos2];
    heap[pos2]=ax;
    int axi;
    int node1,node2;
    node1=heap[pos1].node;
    node2=heap[pos2].node;
    axi=vpos[node1];
    vpos[node1]=vpos[node2];
    vpos[node2]=axi;
}

void heapup(vector <sheap> &heap,vector <int> &vpos,int pos)
{
    if (!safe(heap,pos))
        return;

    if (heap[pos]<heap[pos/2])
    {
        heapswap(heap,vpos,pos,pos/2);
        heapup(heap,vpos,pos/2);
    }
}

int heapmin(vector <sheap> &heap, int pos1, int pos2)
{
    if (heap[pos1]<heap[pos2])
        return pos1;
    return pos2;
}

void heapdown(vector <sheap> &heap, vector <int> &vpos, int pos)
{
    if (!safe(heap,pos*2))
        return;

    int posdown;

    if (!safe(heap,pos*2+1))
        posdown=pos*2;
    else
        posdown=heapmin(heap,pos*2,pos*2+1);

    if (heap[posdown]<heap[pos])
    {
        heapswap(heap,vpos,posdown,pos);
        heapdown(heap,vpos,posdown);
    }
}

void heapinsert(vector <sheap> &heap,vector <int> &vpos,sheap val)
{
    heap.push_back(val);
    int pos=heap.size()-1;
    vpos[val.node]=pos;
    heapup(heap,vpos,pos);
}

//delete last one
void heapdelete(vector <sheap> &heap,vector <int> &vpos)
{
    int pos=heap.size()-1;
    sheap ax=heap[pos];
    vpos[ax.node]=0;
    heap.pop_back();
}

void heapdelete(vector <sheap> &heap,vector <int> &vpos,int pos)
{
    if (!safe(heap,pos))
        return;
    int last=heap.size()-1;
    heapswap(heap,vpos,pos,last);
    heapdelete(heap,vpos);
    if (!safe(heap,pos))
        return;
    heapup(heap,vpos,pos);
    heapdown(heap,vpos,pos);
}

void heapupdate(vector <sheap> &heap, vector <int> &vpos, int pos, sheap arg)
{
    heap[pos]=arg;
    heapup(heap,vpos,pos);
    heapdown(heap,vpos,pos);
}

class dijkstra
{
    private:vector <sheap> heap;
    private:vector <int> vpos;
    public:vector <int> dist;
    dijkstra(int nrnodes)
    {
        init(heap);
        for (int i=0;i<nrnodes;i++)
        {
            vpos.push_back(0);
            dist.push_back(inf);
        }
    }
    bool add_or_update(sheap upd)
    {
        if (upd.node>=vpos.size())
            return false;
        if (upd.node<0)
            return false;
        int node=upd.node;
        dist[node]=upd.val;
        if (vpos[node]==0)
            heapinsert(heap,vpos,upd);
        else
            heapupdate(heap,vpos,vpos[node],upd);
        return true;
    }
    bool topdelete()
    {
        if (heap.size()<=1)
            return false;
        heapdelete(heap,vpos,1);
        return true;
    }
    sheap top()
    {
        return heap[1];
    }
    bool empty()
    {
        if (heap.size()<=1)
            return true;
        return false;
    }
};

int n,m,i,a,b,c,to,cost,now,dnow;
sheap axs;

vector <pair <int,int> > muchii[50005];

int main(void)
{
    FILE * f;
    f=fopen("dijkstra.in","r");
    ofstream g("dijkstra.out");
    fscanf(f,"%d%d",&n,&m);
    dijkstra d(n+1);
    for (i=0;i<m;i++)
    {
        fscanf(f,"%d%d%d",&a,&b,&c);
        muchii[a].push_back(make_pair(b,c));
    }

    axs.val=0;
    axs.node=1;
    d.add_or_update(axs);

    while (!d.empty())
    {
        now=(d.top()).node;
        dnow=(d.top()).val;
        for (i=0;i<muchii[now].size();i++)
        {
            to=muchii[now][i].first;
            cost=muchii[now][i].second;
            if (dnow+cost<d.dist[to])
            {
                axs.node=to;
                axs.val=dnow+cost;
                d.add_or_update(axs);
            }
        }
        d.topdelete();
    }
    for (i=2;i<=n;i++)
        g<<d.dist[i]<<' ';
    return 0;
}