Cod sursa(job #407138)

Utilizator dead_knightTitei Paul Adrian dead_knight Data 2 martie 2010 08:45:31
Problema Distante Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.17 kb
using namespace std;
#include<iostream>
#include<cstdio>
#define MAX 50006
#define INFINIT 50000001
inline int father(int k){
    return k/2;}
inline int left_son(int k){
    return k*2;}
inline int right_son(int k){
    return k*2+1;}
struct nod{
    int info,c;
    nod *next;
};

nod *G[MAX];
int heap[MAX],poz[MAX],d[MAX],v[MAX],t[MAX],n,nh,S,ddat[MAX];

void afis()
{
    int i;
    nod *p;
    for(i=1;i<=n;i++)
    {
        printf("%d: ", i);
        for(p=G[i]; p ;p=p->next)
            printf("%d ", p->info);
        printf("\n");
    }
}

void sterge()
{
    for(int i=1;i<=n;i++)
    {
        for(nod *p=G[i]; p ; )
        {
            nod *t=p;
            p=p->next;
            delete t;
        }
    }
}

void addmuchie(int x,int y, int cost)
{
    nod *p=new nod;
    p->c=cost;
    p->info=y;
    p->next=G[x];
    G[x]=p;
    p=new nod;
    p->c=cost;
    p->info=x;
    p->next=G[y];
    G[y]=p;
}

void promoveaza(int k)
{
    while(k>1 && d[heap[father(k)]]>d[heap[k]])
    {
        swap(heap[k],heap[father(k)]);
        swap(poz[heap[k]],poz[heap[father(k)]]);
        k=father(k);
    }
}

void cerne(int k)
{
    int son;
    do
    {
        son=0;
        if(left_son(k)<=nh)
        {
            son=left_son(k);
            if(right_son(k)<=nh && d[heap[right_son(k)]]<d[heap[son]])
                son=right_son(k);
            if(d[heap[son]]>=d[heap[k]])
                son=0;
        }
        if(son)
        {
            swap(heap[k],heap[son]);
            swap(poz[heap[k]],poz[heap[son]]);
            k=son;
        }
    }while(son);
}


void init(int sursa)
{
    int i;
    for(i=0;i<=n;i++)
        v[i]=0,d[i]=INFINIT,heap[i]=i,poz[i]=i,t[i]=0;
    nh=n;
    v[sursa]=1,d[sursa]=0,t[sursa]=0;
    heap[sursa]=heap[nh--];
    poz[heap[sursa]]=sursa;
    cerne(1);
    for(nod *p=G[sursa]; p ; p=p->next)
    {
        d[p->info]=p->c;
        t[p->info]=sursa;
        promoveaza(poz[p->info]);
    }
}

void dijkstra(int sursa)
{
    init(sursa);
    for(int qq=1;qq<n;qq++)
    {
        int pmin=heap[1];
        v[pmin]=1;
        heap[1]=heap[nh--];
        poz[heap[1]]=1;
        cerne(1);
        for(nod *p=G[pmin];p;p=p->next)
            if(d[p->info]>(d[pmin]+p->c))
            {
                t[p->info]=pmin;
                d[p->info]=d[pmin]+p->c;
                promoveaza(poz[p->info]);
            }
    }
}

int main()
{
    freopen("distante.in","r",stdin);
    freopen("distante.out","w",stdout);
    int T,m,i,x,y,cost;
    scanf("%d", &T);
    for(;T;T--)
    {
        scanf("%d %d %d", &n, &m, &S);
        for(i=1;i<=n;i++)
            scanf("%d", &ddat[i]),G[i]=NULL;
        for(i=1;i<=m;i++)
        {
            scanf("%d %d %d", &x, &y, &cost);
            addmuchie(x,y,cost);
        }
        //afis();
        dijkstra(S);
        int pp=1;
        for(i=1;i<=n;i++)
        {
            //printf("%d ",d[i]);
            if(d[i]!=ddat[i])
                pp=0;
        }
        if(pp)
            printf("DA\n");
        else
            printf("NU\n");
        sterge();
    }
}