Cod sursa(job #1201609)

Utilizator gapdanPopescu George gapdan Data 25 iunie 2014 15:31:37
Problema Distante Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.36 kb
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cmath>
#define NMAX 50001
using namespace std;
struct gf
{
    int l,r;
};
vector<gf>v[NMAX];
int H[NMAX*2+1],Poz[NMAX],a[NMAX],cost[NMAX];
int n,m,s,i,lg,t,x,y,c;
void pop(int poz)
{
    while (poz>1 && cost[H[poz]]<cost[H[poz/2]])
    {
        swap(H[poz],H[poz/2]);
        swap(Poz[H[poz]],Poz[H[poz/2]]);
        poz=poz/2;
    }
}
void bagaheap(int nod)
{
    ++lg;
    H[lg]=nod;
    Poz[nod]=lg;
    pop(lg);
}
void coboara(int poz)
{
    while((poz*2<=lg && cost[H[poz]]>cost[H[poz*2]]) || (poz*2+1<=lg+1 && cost[H[poz]]>cost[H[poz*2+1]]))
    {
        if (cost[H[poz*2]]<cost[H[poz*2+1]] || poz*2+1>lg)
        {
            swap(H[poz],H[poz*2]);
            swap(Poz[H[poz]],Poz[H[poz*2]]);
            poz*=2;
        }
        else
        {
            swap(H[poz],H[poz*2+1]);
            swap(Poz[H[poz]],Poz[H[poz*2+1]]);
            poz=poz*2+1;
        }
    }
}
int Minim()
{
    int Min=H[1];
    swap(H[1],H[lg]);
    swap(Poz[1],Poz[lg]);
    --lg;
    coboara(1);
    return Min;
}
int main()
{
    freopen("distante.in","r",stdin);
    freopen("distante.out","w",stdout);
    scanf("%d",&t);
    for (int o=1;o<=t;++o)
    {
        scanf("%d%d%d",&n,&m,&s);
        for (i=1;i<=n;++i) scanf("%d",&a[i]);
        for (i=1;i<=m;++i)
        {
            gf X;
            scanf("%d%d%d",&x,&y,&c);
            X.l=y,X.r=c;
            v[x].push_back(X);
            X.l=x;
            v[y].push_back(X);
        }
        for (i=1;i<=n;++i)
        {
            Poz[i]=0;
            cost[i]=INFINITY;
        }
        Poz[s]=1;
        cost[s]=0;
        bagaheap(s);
        for (i=1;i<=n;++i)
        {
            int u=Minim();
            vector<gf>::iterator it;
            for (it=v[u].begin();it!=v[u].end();++it)
            {
                gf p=*it;
                if (cost[p.l]>p.r+cost[u])
                    {
                        cost[p.l]=p.r+cost[u];
                        if (Poz[p.l]==0) bagaheap(p.l);
                            else pop(p.l);
                    }
            }
        }
        int e=0;
        for (i=1;i<=n;++i)
        {
            if (cost[i]!=a[i]) {e=1;break;}
        }
        if (e==0) printf("DA\n");
            else printf("NU\n");
    }
    return 0;
}