Cod sursa(job #215133)

Utilizator ProtomanAndrei Purice Protoman Data 17 octombrie 2008 17:25:19
Problema Distante Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.67 kb
#include <stdio.h>   
#include <algorithm>   
#define sec second   
#define fir first   
#define mx 110000   
  
using namespace std;   
  
struct nod   
{   
    int nr, d;   
    nod *ua;   
} *l[mx], *p;   
pair <int, int> hp[mx];   
int dist[mx], eih[mx], sd[mx];   
int t, s, n, m, lmin, dimh, n1, n2, c;   
  
void clad(int t, int f, int cost)   
{   
    nod *p = new nod;   
    p->nr = n2;   
    p->d = cost;   
    p->ua = l[t];   
    l[t] = p;   
}   
  
void swap(int i, int j)   
{   
    pair <int, int> aux = hp[i];   
    hp[i] = hp[j];   
    hp[j] = aux;   
    eih[hp[i].sec] = i;   
    eih[hp[j].sec] = j;   
}   
  
void heapup(int i)   
{   
    if (i > 1)   
        if (hp[i].fir < hp[i / 2].fir)   
        {   
            swap(i, i / 2);   
            heapup(i / 2);   
        }   
}   
  
void heapdown(int i)   
{   
    if (i << 1 <= dimh)   
    {   
        int f = i << 1;   
        if (f < dimh && hp[f + 1].fir < hp[f].fir)   
            f++;   
        if (hp[i].fir > hp[f].fir)   
        {   
            swap(i, f);   
            heapdown(f);   
        }   
    }   
}   
  
int main()   
{   
    freopen("distante.in","r",stdin);   
    freopen("distante.out","w",stdout);   
    for (scanf("%d", &t); t; t--)   
    {   
        dimh = 0;   
        scanf("%d %d %d", &n, &m, &s);   
        memset(sd, 0, sizeof(sd));   
        memset(eih, 0, sizeof(eih));   
        for (int i = 1; i < mx; i++)   
        {   
            dist[i] = LONG_MAX;   
            hp[i].fir = 0;   
            hp[i].sec = 0;   
        }   
        dist[s] = 0;   
        for (int i = 1; i <= n; i++)   
            scanf("%d", &sd[i]);   
        for (int i = 1; i <= m; i++)   
        {   
            scanf("%d %d %d", &n1, &n2, &c);   
            clad(n1, n2, c);   
            clad(n2, n1, c);   
        }   
        for (nod *p = l[s]; p; p = p->ua)   
        {   
            dimh++;   
            dist[p->nr] = p->d;   
            hp[dimh].fir = p->d;   
            hp[dimh].sec = p->nr;   
            eih[p->nr] = dimh;   
            heapup(dimh);   
        }   
        int minim = 1;   
        for (; minim; )   
        {   
            minim = hp[1].sec;   
            lmin = hp[1].fir;   
            for (nod *p = l[minim]; p; p = p->ua)   
                if (p->d + lmin < dist[p->nr])   
                {   
                    dist[p->nr] = p->d + lmin;   
                    if (!eih[p->nr])   
                    {   
                        dimh++;   
                        eih[p->nr] = dimh;   
                        hp[dimh].fir = dist[p->nr];   
                        hp[dimh].sec = p->nr;   
                    }   
                    else hp[eih[p->nr]].fir = dist[p->nr];   
                    heapup(eih[p->nr]);   
                }   
            hp[1] = hp[dimh];
			hp[dimh].fir = 1;
			hp[dimh].sec = 1;
            eih[hp[1].sec] = 1;   
            dimh--;   
            heapdown(1);   
        }   
        bool ok = 1;   
        for (int i = 1; i <= n; i++)   
            if (dist[i] == LONG_MAX)   
                dist[i] = 0;   
        for (int i = 1; i <= n; i++)   
            if (dist[i] != sd[i])   
                ok = 0;   
        if (ok)   
            printf("DA\n");   
        else printf("NU\n");   
        for (int i = 1; i <= n; l[i] = NULL, i++)   
            for (nod *p = l[i]; p; )   
            {   
                nod *u = p;   
                p = p->ua;   
                delete u;   
            }   
    }   
    fclose(stdin);   
    fclose(stdout);   
    return 0;   
}