Cod sursa(job #932308)

Utilizator gabrielvGabriel Vanca gabrielv Data 28 martie 2013 20:26:22
Problema Distante Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.67 kb
#include <cstdio>
#include <vector>

#define NMAX 50100
#define vecin first
#define cost second

using namespace std;

int N,M,Nheap,S;

int H[NMAX];
int P[NMAX];
int D[NMAX];
int A[NMAX];

struct node_structure {
    int vecin,cost;
};

vector < node_structure > G[NMAX];

inline int father(int nod) {

    return  nod>>1;
}

inline int left_son(int nod) {

    return nod<<1;
}

inline int right_son(int nod) {

    return (nod<<1)+1;
}

inline bool cmp(int i, int j) {

    return( D[H[i]] < D[H[j]] );
}

void percolate(int nod) {

    while(nod>1 && cmp(nod,father(nod))) {
        swap(H[nod],H[father(nod)]);
        swap(P[H[nod]],P[H[father(nod)]]);
        nod=father(nod);
    }
}

void sift(int nod) {

    int son;
    do {
        son=0;
        if(left_son(nod)<=Nheap) {
            son=left_son(nod);
            if(right_son(nod)<=Nheap && cmp(right_son(nod),son))
                son=right_son(nod);
            if(cmp(nod,son))
                son=0;
        }

        if(son) {
            swap(H[nod],H[son]);
            swap(P[H[nod]],P[H[son]]);
            nod=son;
        }
    }while(son);
}

void Read() {

    int x,y,c;
    scanf("%d%d%d",&N,&M,&S);
    for(int i=1;i<=N;++i)
        scanf("%d",&A[i]);
    while(M--) {
        scanf("%d%d%d",&x,&y,&c);
        G[x].push_back({y,c});
        G[y].push_back({x,c});
    }
}

void Reset(int Nr) {

    for(int i=1;i<=Nr;i++) {
        H[i]=P[i]=D[i]=A[i]=0;
        G[i].clear();
    }
}

void Dijkstra(int sursa) {

    int svec,nod;
    Nheap=1;
    H[1]=sursa;
    P[sursa]=1;

    while(Nheap) {

        nod=H[1];
        P[nod]=-1;
        H[1]=H[Nheap--];
        P[H[1]]=1;
        sift(1);

        for(unsigned i=0;i<G[nod].size();++i) {
            svec=G[nod][i].vecin;
            if(!P[svec]) {
                H[++Nheap]=svec;
                P[svec]=Nheap;
                D[svec]=D[nod]+G[nod][i].cost;
                percolate(Nheap);
            }
            else {
                if(D[svec]>D[nod]+G[nod][i].cost) {
                    D[svec]=D[nod]+G[nod][i].cost;
                    percolate(P[svec]);
                }
            }
        }
    }
}

void Print() {

    bool ok=true;
    for(int i=1;i<=N && ok;i++)
        if(D[i]!=A[i])
            ok=false;
    if(ok)
        printf("DA\n");
    else
        printf("NU\n");
}

int main() {

    freopen("distante.in","r",stdin);
    freopen("distante.out","w",stdout);

    int T;

    scanf("%d",&T);
    while(T--) {
        Read();
        Dijkstra(S);
        Print();
        Reset(N);
    }
    return 0;
}