Cod sursa(job #388462)

Utilizator popoiu.georgeGeorge Popoiu popoiu.george Data 30 ianuarie 2010 11:19:39
Problema Distante Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.39 kb
#include<fstream>
#define inf "distante.in"
#define outf "distante.out"
#define NMax 50010
#define INF 0x3f3f3f3f
using namespace std;

fstream f(inf,ios::in),g(outf,ios::out);

struct graf
{
int nod;
int cost;
graf *next;
};

int T,N,M,S;
int b[NMax];
int dim;
int d[NMax];
int heap[NMax];
int pos[NMax];
graf *a[NMax];

void add(int x,int y,int c)
{
graf *gr=new graf;
gr->nod=y;
gr->cost=c;
gr->next=a[x];
a[x]=gr;
}

void downheap(int nodh)
{
int f;
while(nodh<=dim)
    {
    f=nodh<<1;
    if(f<=dim)
        {
        if( (f+1)<=dim && d[heap[f+1]]<d[heap[f]] )f++;
        else return;
        }
    else return;
    if(d[heap[f]]<d[heap[nodh]])
            {
            pos[heap[f]]=nodh;
            pos[heap[nodh]]=f;
            swap(heap[f],heap[nodh]);
            nodh=f;
            }
    else return;
    }
}

void upheap(int nodh)
{
int t;
while(nodh>1)
    {
    t=nodh>>1;
    if(d[heap[nodh]]<d[heap[t]])
        {
        pos[heap[nodh]]=t;
        pos[heap[t]]=nodh;
        swap(heap[nodh],heap[t]);
        nodh=t;
        }
    else return;
    }
}

void Dijkstra()
{
if(b[S]!=0){g<<"NU\n";return;}
int min;
d[S]=0;
heap[1]=S;
pos[S]=1;
dim++;
while(dim)
    {
    min=heap[1];
    swap(heap[1],heap[dim]);
    pos[heap[1]]=1;
    dim--;
    downheap(1);

    graf *t=a[min];
    while(t)
        {
        if(d[t->nod]>d[min]+t->cost)
            {
            d[t->nod]=d[min]+t->cost;
            if(d[t->nod]<b[t->nod]){g<<"NU\n";return;}
            if(pos[t->nod]!=-1)upheap(pos[t->nod]);
            else
                {
                dim++;
                heap[dim]=t->nod;
                pos[heap[dim]]=dim;
                upheap(dim);
                }
            }
        t=t->next;
        }
    }
/*for(int i=1;i<=N;i++)g<<d[i]<<" ";
g<<"\n";*/
for(int i=1;i<=N;i++)
    {
    if(d[i]!=b[i]){g<<"NU\n";return;}
    }
g<<"DA\n";
}

void init()
{
dim=0;
for(int i=1;i<=N;i++)
    {
    a[i]=NULL;
    d[i]=INF;
    pos[i]=-1;
    }
}

void Citire()
{
int x,y,c;
f>>T;
for(int k=1;k<=T;k++)
    {
    f>>N>>M>>S;
    init();
    for(int i=1;i<=N;i++)f>>b[i];
    for(int i=1;i<=M;i++)
        {
        f>>x>>y>>c;
        add(x,y,c);
        add(y,x,c);
        }
    Dijkstra();
    }
}

int main()
{
Citire();
f.close();
g.close();
return 0;
}