Cod sursa(job #2039923)

Utilizator Ruxandra985Nanu Ruxandra Laura Ruxandra985 Data 15 octombrie 2017 08:46:22
Problema Distante Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.01 kb
#include <cstdio>
#include <vector>
#include <algorithm>
#define INF 2000000000

using namespace std;
int poz[50001],f[50001];
vector <pair <int,int> > v[100001];
pair <int,int> h[50001];
int elem;
int d[50001],drez[50001];
void adauga (int val,int nod){
    int c,p;
    elem++;
    poz[nod]=elem;
    h[elem].first=val;
    h[elem].second=nod;
    c=elem;
    p=elem/2;
    while (p>0){
        if (h[c].first<h[p].first){
            swap (poz[h[c].second],poz[h[p].second]);
            swap (h[c],h[p]);
        }
        else break;
        c=p;
        p/=2;
    }
}
void sterge (){
    int c,p;
    h[1].first=h[elem].first;
    h[1].second=h[elem].second;
    poz[h[elem].second]=1;
    elem--;
    p=1;
    c=2;
    while (c<=elem){
        if (c+1<=elem && h[c+1].first<h[c].first)
            c++;
        if (h[c].first<h[p].first){
            swap (poz[h[c].second],poz[h[p].second]);
            swap (h[c],h[p]);
        }
        else break;
        p=c;
        c*=2;
    }
}
void update (int nod){
    int po,c,p;
    po=poz[nod];
    // po = pozitia nodului pe care l-am updatat in heap
    c=po;
    p=po/2;
    while (p>0){
        if (h[c].first<h[p].first){
            swap (poz[h[c].second],poz[h[p].second]);
            swap (h[c],h[p]);
        }
        else break;
        c=p;
        p/=2;
    }
}
int main()
{
    FILE *fin=fopen ("distante.in","r");
    FILE *fout=fopen ("distante.out","w");
    int n,m,i,nod,vecin,x,y,z,p,mini,cost,t;
    fscanf (fin,"%d",&t);
    for (;t;t--){
        fscanf (fin,"%d%d%d",&n,&m,&p);
        for (i=1;i<=n;i++)
            fscanf (fin,"%d",&drez[i]);
        for (i=1;i<=m;i++){
            fscanf (fin,"%d%d%d",&x,&y,&z);
            v[x].push_back (make_pair (y,z) );
            v[y].push_back (make_pair (x,z) );
        }
        // h.first = valoare
        // h.second = nodul
        // poz[nod] = pe ce poz se afla nodul nod in heap
        elem=0;
        for (i=1;i<=n;i++){
            adauga (INF,i);
            d[i]=INF;
        }
        h[poz[p]].first=0;
        update (p);
        for (;;){
            nod=h[1].second;
            mini=h[1].first;
            if (mini==INF)
                break;
            //printf ("%d %d\n",nod,mini);
            sterge ();
            if (mini!=drez[nod])
                break;
            d[nod]=mini;
            f[nod]=1;
            for (vector <pair <int,int> > :: iterator it=v[nod].begin() ; it!=v[nod].end() ; it++){
                vecin=it->first;
                cost=it->second;
                if (f[vecin]==0 && cost+mini<h[poz[vecin]].first){
                    h[poz[vecin]].first=cost+mini;
                    update (vecin);
                }
            }
            if (elem<=0)
                break;
        }
        for (i=1;i<=n;i++)
            if (d[i]!=drez[i])
                break;
        if (i<=n)
            fprintf (fout,"NU\n");
        else fprintf (fout,"DA\n");
    }
    return 0;
}