Cod sursa(job #491756)

Utilizator marius21Marius Petcu marius21 Data 12 octombrie 2010 12:20:08
Problema Algoritmul lui Dijkstra Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 2.28 kb
#include <cstdio>
FILE * fin = fopen("dijkstra.in","r");
FILE * fout = fopen("dijkstra.out","w");

struct muchie
{
    int y;
    int c;
    struct muchie * next;
};

muchie * vc[50000];
bool chk[50000];

int hp[50000];
long long d[50000];
int pos[50000];
int n;

inline void hp_swap(int a, int b)
{
    hp[a]=hp[a]^hp[b];
    hp[b]=hp[a]^hp[b];
    hp[a]=hp[a]^hp[b];
    pos[hp[a]]=a;
    pos[hp[b]]=b;
}

inline int hp_comp(int a, int b)
{
    return d[hp[a]]<d[hp[b]];
}


void hp_up(int i)
{
    while (i)
    {
        int pos = ((i+1)>>1)-1;
        if (hp_comp(pos,i))
            break;
        hp_swap(i,pos);
        i=pos;
    }
}

void hp_down(int i)
{
    while (1)
    {
        int p1 = (i<<1) + 1;
        int p2 = (i<<1) + 2;
        int min = i;
        if ((p1<n)&&hp_comp(p1,min))
            min=p1;
        if ((p2<n)&&hp_comp(p2,min))
            min=p2;
        if (min==i)
            break;
        hp_swap(i,min);
        i=min;
    }
}

inline int hp_pop()
{
    int res = hp[0];
    n--;
    hp_swap(0,n+1);
    hp_down(0);
    return res;
}

inline void hp_push(int i)
{
    hp[n]=i;
    pos[i]=n;
    n++;
    hp_up(n-1);
}

#define INF 0x3f3f3f3f

int main()
{
    int n,m;
    fscanf(fin,"%d%d",&n,&m);
    ::n=n;
    for (int i=0; i<n; i++)
    {
        hp[i]=i;
        pos[i]=i;
        d[i]=INF;
        chk[i]=0;
        vc[i]=NULL;
    }
    d[0]=0;
    for (int i=0; i<m; i++)
    {
        int x,y,z;
        fscanf(fin,"%d %d %d",&x, &y, &z);
        x--; y--;
        muchie * mch = new muchie;
        mch->c=z;
        mch->y=y;
        mch->next=vc[x];
        vc[x]=mch;
    }
    for (int i=0; i<n; i++)
    {
        int crnt = hp_pop();
        chk[crnt]=1;
        for (muchie * j = vc[crnt]; j!=NULL; j=j->next)
        {
            int y = (*j).y;
            int c = (*j).c;
            if (chk[y]) continue;
            if (d[crnt]+c<d[y])
            {
                d[y]=d[crnt]+c;
                hp_up(pos[y]);
            }
        }
    }
    for (int i=1; i<n; i++)
    {
        if (d[i]==INF)
            d[i]=0;
        fprintf(fout,"%lld ",d[i]);
    }
    fputc('\n',fout);
    fclose(fin);
    fclose(fout);
    return 0;
}