Cod sursa(job #875084)

Utilizator gabriel93Robu Gabriel gabriel93 Data 9 februarie 2013 18:04:51
Problema Distante Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.36 kb
#include<stdio.h>
#define Nmax 50002
using namespace std;
int s,n,m,t,nh;

struct graf
{
    int v,c;
    graf *adr;
};

struct heap
{
    int v,c;
};

graf *g[Nmax];
heap h[100002];
int viz[Nmax];
int d[Nmax];

void heap_swap(int x,int y)
{
    heap aux;
    aux=h[x];
    h[x]=h[y];
    h[y]=aux;
}

void heap_down(int x)
{
    int fs,fd,k;
    do
    {
        k=0;
        fs=x<<1;
        fd=fs+1;
        if(fs<=nh)
        {
            k=fs;
            if(fd<=nh && h[fd].c < h[fs].c)
                k=fd;
            if(h[k].c > h[x].c)
                k=0;
        }
        if(k)
        {
            heap_swap(x,k);
            x=k;
        }
    }while(k);
}

void heap_up(int x)
{
    int t;
    t=x>>1;
    while(t>1 && h[x].c < h[t].c)
    {
        heap_swap(x,t);
        x=t;
        t=x>>1;
    }
}

void heap_add(int v,int c)
{
    ++nh;
    h[nh].v=v;
    h[nh].c=c;
    heap_up(nh);
}

void heap_delete()
{
    h[1]=h[nh];
    --nh;
    heap_down(1);
}

int dijkstra(int x)
{
    int v,c,k;
    graf *p;
    nh=0;
    for(p=g[x];p;p=p->adr)
        heap_add(p->v,p->c);
    viz[x]=1;
    k=1;
    while(nh>0 && k<n)
    {
        v=h[1].v;
        c=h[1].c;
        heap_delete();
        if(viz[v]==0)
        {
            if(c!=d[v])
                return 0;
            ++k;
            viz[v]=1;
            for(p=g[v];p;p=p->adr)
                if(viz[p->v]==0)
                    heap_add(p->v,c+p->c);
        }
    }
    return 1;
}

void graf_add(int v1,int v2,int c)
{
    graf *p;
    p=new graf;
    p->v=v2;
    p->c=c;
    p->adr=g[v1];
    g[v1]=p;
}

void citire()
{
    int i,x,y,c;
    scanf("%d %d %d",&n,&m,&s);
    for(i=1;i<=n;++i)
    {
        g[i]=0;
        viz[i]=0;
        scanf("%d",&d[i]);
    }
    for(i=1;i<=m;++i)
    {
        scanf("%d %d %d",&x,&y,&c);
        graf_add(x,y,c);
        graf_add(y,x,c);
    }
}

void rezolv()
{
    int i,ok;
    scanf("%d",&t);
    for(i=1;i<=t;++i)
    {
        citire();
        ok=dijkstra(s);
        if(ok==0)
            printf("NU\n");
        else
            printf("DA\n");
    }

}
int main()
{
    freopen("distante.in","r",stdin);
    freopen("distante.out","w",stdout);
    rezolv();
    fclose(stdin);
    fclose(stdin);
    return 0;
}