Cod sursa(job #1655049)

Utilizator llalexandruLungu Alexandru Ioan llalexandru Data 17 martie 2016 18:12:25
Problema Algoritmul lui Dijkstra Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 4.22 kb
#include <fstream>
#include <stdlib.h>
#define NM 36005
#define inf 1000000000

using namespace std;

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

void Citire();
void Initializare();
void Dijkstra();

struct nod{long long val; int idx, prov;};
struct lista{int nume, cost;};
struct distanta{long long m; int o;};

int n, m, original;
lista *A[NM];

nod heap[NM];
int last=0;

distanta d[NM];
int loc[NM];

int F[NM];

int main()
{
    int i, j;
    Citire();
    Initializare();
    Dijkstra();
    for (i=1; i<=n; i++)
    {
        fout<<d[i].o<<" ";
    }
    return 0;
}

void Citire()
{
    int i, x, y, c, f;
    fin>>n>>m>>f;
    for (i=1; i<=f; i++)
    {
        fin>>x;
        F[x]=1;
    }
    for (i=1; i<=n; i++)
    {
        A[i] = (lista *) realloc(A[i], 2*sizeof(int));
        A[i][0].nume=0;
    }
    for (i=1; i<=m; i++)
    {
        fin>>x>>y>>c;
        A[x][0].nume++;
        A[x] = (lista *) realloc(A[x], (A[x][0].nume+1)*2*sizeof(int));
        A[x][A[x][0].nume].nume=y;
        A[x][A[x][0].nume].cost=c;
        A[y][0].nume++;
        A[y] = (lista *) realloc(A[y], (A[y][0].nume+1)*2*sizeof(int));
        A[y][A[y][0].nume].nume=x;
        A[y][A[y][0].nume].cost=c;
    }
}

void Initializare()
{
    int i;
    heap[0].val=inf;
    last=0;
    for (i=1; i<=n; i++)
    {
        d[i].m=inf;
        loc[i]=0;
    }
    for (i=1; i<=n; i++)
        if (F[i]==1)
            d[i].m=0;
}

void Add(int who, long long price, int org)
{
    last++;
    int act=last;
    while (price < heap[act/2].val && act>1)
    {
        loc[heap[act/2].idx]=act;
        heap[act]=heap[act/2];
        act=act/2;
    }
    heap[act].val=price;
    heap[act].idx=who;
    heap[act].prov=org;
    loc[who]=act;
}

void Edit(int place, long long update, int who, int org)
{
    int act=place;
    while (update < heap[act/2].val && act>1)
    {
        loc[heap[act/2].idx]=act;
        heap[act]=heap[act/2];
        act=act/2;
    }
    heap[act].val=update;
    heap[act].idx=who;
    heap[act].prov=org;
    loc[who]=act;
}

int Pop()
{
    long long a, b;
    nod imp=heap[last];
    int deretur=heap[1].idx;
    original=heap[1].prov;
    loc[heap[1].idx]=0;
    heap[last].idx=0;
    heap[last].val=0;
    heap[last].prov=0;
    last--;
    int act=1;
    while ((heap[act*2+1].val<imp.val && heap[act*2+1].val>0) || (heap[act*2].val<imp.val && heap[act*2].val>0))
    {
        a=heap[act*2].val;
        b=heap[act*2+1].val;
        if (a>0 && b>0)
        {
            if (a>b)
            {
                loc[heap[act*2+1].idx]=act;
                heap[act]=heap[act*2+1];
                act=act*2+1;
            }
            else
            {
                loc[heap[act*2].idx]=act;
                heap[act]=heap[act*2];
                act=act*2;
            }

        }
        else
        {
            if (a>0)
            {
                loc[heap[act*2].idx]=act;
                heap[act]=heap[act*2];
                act=act*2;
            }
            else
            {
                loc[heap[act*2].idx]=act;
                heap[act]=heap[act*2];
                act=act*2;
            }
        }
    }
    heap[act]=imp;
    loc[imp.idx]=act;
    return deretur;
}

void Dijkstra()
{
    long long i, p, c, x;
    for (i=1; i<=n; i++)
    {
        if (F[i]==1)
            Add(i, 0, i);
    }
    x=Pop();
    while (x!=0)
    {
        for (i=1; i<=A[x][0].nume; i++)
        {
            p=A[x][i].nume;
            c=A[x][i].cost;
            if (d[p].m==inf)
            {
                d[p].m=c+d[x].m;
                d[p].o=original;
                Add(p, c+d[x].m, original);
            }
            else
            {
                if (d[p].m>c+d[x].m)
                {
                    d[p].m=c+d[x].m;
                    d[p].o=original;
                    Edit(loc[p], c+d[x].m, p, original);
                }
                else
                {
                    if (d[p].m==c+d[x].m)
                        d[p].o=min(d[p].o, original);
                }
            }
        }
        x=Pop();
    }
}