Cod sursa(job #492874)

Utilizator marius21Marius Petcu marius21 Data 16 octombrie 2010 11:26:22
Problema Distante Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.8 kb
#include <cstdio>

FILE * fin = fopen("distante.in","r");
FILE * fout = fopen("distante.out","w");

long long potd[50000];

struct muchie
{
    int y;
    long long 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);
    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

void dijkstra(int n, int m, int s)
{
    ::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[s]=0;
    hp_up(s);
    for (int i=0; i<m; i++)
    {
        int x,y;
		long long z;
        fscanf(fin,"%d %d %lld",&x, &y, &z);
        x--; y--;
        muchie * mch = new muchie;
        mch->c=z;
        mch->y=y;
        mch->next=vc[x];
        vc[x]=mch;
		
        mch = new muchie;
        mch->c=z;
        mch->y=x;
        mch->next=vc[y];
        vc[y]=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;
            long long 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=0; i<n; i++)
    {
        muchie * mch = vc[i];
        vc[i]=0;
        while (mch)
        {
            muchie * next = mch->next;
            delete mch;
            mch=next;
        }
    }
}

int main()
{
    int t;
    fscanf(fin,"%d",&t);
    for (int i=0; i<t; i++)
    {
        int n,m,s;
        fscanf(fin,"%d%d%d",&n,&m,&s);
        for (int i=0; i<n; i++)
            fscanf(fin,"%lld",&potd[i]);
        dijkstra(n,m,s-1);
        bool ok = true;
        for (int i=0; i<n; i++)
            if (d[i]!=potd[i])
            {
                ok=false;
                break;
            }
        fprintf(fout,ok?"DA\n":"NU\n");
    }
    fclose(fin);
    fclose(fout);
    return 0;
}