Cod sursa(job #1712343)

Utilizator antanaAntonia Boca antana Data 2 iunie 2016 18:09:09
Problema Distante Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.75 kb
#include <cstdio>
#define MAXN 50000
#define MAXM 100000
#define INF (1<<30)

struct muchie{
    int val, cost;
}v[2*MAXM+1];
int lista[MAXN+1], next[2*MAXM+1], dist[MAXN+1], poz[MAXN+1], heap[MAXN+1], vf[MAXN+1], k, r;
inline void adauga(int x, int y, int z)
{
    v[++r].val=y;
    v[r].cost=z;
    next[r]=lista[x];
    lista[x]=r;
}
inline int father(int x){ return x/2;}
inline int son_left(int x){ return x*2;}
inline int son_right(int x){ return x*2+1;}
inline void swap1(int a, int b)
{
    int aux=heap[a];
    poz[heap[a]]=b;
    poz[heap[b]]=a;
    heap[a]=heap[b];
    heap[b]=aux;
}
inline void up(int x)
{
    int p, f=1;
    while(father(x) && f)
    {
        f=0;
        p=father(x);
        if(dist[heap[p]] > dist[heap[x]])
        {
            f=1;
            swap1(p, x);
        }
        x=p;
    }
}
inline void down(int x)
{
    int p, q, f=1;
    while(son_left(x)<=k && f)
    {
        p=son_left(x);
        q=son_right(x);
        if(q<=k && dist[heap[q]] < dist[heap[p]])
                p=q;
        if(dist[heap[p]] < dist[heap[x]])
        {
            f=1;
            swap1(p, x);
        }
        x=p;
    }
}
inline void add(int x)
{
    heap[++k]=x;
    poz[x]=k;
    up(k);
}
inline void delete1()
{
    swap1(1, k);
    k--;
    down(1);
}
inline void dijkstra_heap(int s)
{
    int p, nod, vecin;
    dist[s]=0;
    add(s);
    while(k)
    {
        nod=heap[1];
        delete1();
        p=lista[nod];
        while(p)
        {
            vecin=v[p].val;
            if(dist[vecin] > dist[nod]+v[p].cost)
            {
                dist[vecin]=dist[nod]+v[p].cost;
                if(poz[vecin]!=-1)
                {
                    up(poz[vecin]);
                    down(poz[vecin]);
                }
                else add(vecin);
            }
            p=next[p];
        }
    }
}
inline void init(int n)
{
    r=k=0;
    for(int i=1;i<=n;++i)
    {
        dist[i]=INF;
        poz[i]=-1;
        lista[i]=0;
    }
}
inline int check(int n)
{
    for(int i=1;i<=n;++i)
        if(vf[i]!=dist[i])
            return 0;
    return 1;
}
int main()
{
    freopen("distante.in", "r",stdin);
    freopen("distante.out", "w", stdout);
    int t, n,m, s, x, y, z;
    scanf("%d", &t);
    for(int a=1;a<=t;++a)
    {
        scanf("%d%d%d", &n, &m, &s);
        init(n);
        for(int i=1;i<=n;++i)
            scanf("%d", &vf[i]);
        for(int i=1;i<=m;++i)
        {
            scanf("%d%d%d", &x, &y, &z);
            adauga(x, y, z);
            adauga(y, x, z);
        }
        dijkstra_heap(s);
        if(check(n))
            printf("DA\n");
        else printf("NU\n");
    }
    return 0;
}