Cod sursa(job #28075)

Utilizator varuvasiTofan Vasile varuvasi Data 7 martie 2007 14:41:56
Problema Distante Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.18 kb
#include <stdio.h>
#define INF 10001
#define MaxN 100001

int N, nheap, M, S;
int heap[MaxN], v[MaxN]; // heap[i] - retine POZITIA minimului din sirul v
int pos[MaxN]; // pozitia lui v[i] in heap;

struct NOD {
    int vf, cost;
    NOD* next;
};

typedef NOD* PNOD;

PNOD L[MaxN];
int dist[MaxN], sel[MaxN];
int pdist[MaxN];

int extrage_min();
void move_up(int poz);
void move_down(int poz);
void modifica(int poz);
void insert_heap(int poz);
void dijkstra(int, int);

void Add(int i, int j, int c)
{
    PNOD p = new NOD;
    p->vf = j;
    p->cost = c;
    p->next = L[i];
    L[i] = p;
}
    
int main()
{
    int i, j, vf1, vf2, c, T;
    
    FILE *fin = fopen("distante.in", "rt");
    FILE *fout = fopen("distante.out", "wt");
    
    fscanf(fin, "%d", &T);
    
    for (;T;T--)
    {
    fscanf(fin, "%d %d %d", &N, &M, &S);
    for (i = 1; i <= N; i++) fscanf(fin, "%d", &pdist[i]);
    for (i = 1; i <= N; i++) L[i] = NULL;
    for (i = 1; i <= M; i++)
    {
        fscanf(fin, "%d %d %d", &vf1, &vf2, &c);
        Add(vf1, vf2, c);
        Add(vf2, vf1, c);
    }    
    
    dijkstra(S, N);
    
    int ok = 1;
    for (i = 1; i <= N; i++)
        if (pdist[i] != dist[i]) ok = 0;
    //for (i = 1; i <= N; i++) fprintf(fout, "%d ", dist[i]);
    if (ok) fprintf(fout, "DA\n");
    else    fprintf(fout, "NU\n");
    }    
    fclose(fin);
    fclose(fout);
    
    return 0;
}

void insert_heap(int poz)
{
    pos[poz] = ++nheap;
    heap[nheap] = poz;
    
    move_up(nheap);
}

void move_up(int poz)
{
    int pnod = heap[poz], fiu = poz, tata = poz / 2;
    while( tata != 0 && v[pnod] < v[heap[tata]])
    {
	    pos[heap[tata]] = pos[heap[fiu]];
	    heap[fiu] = heap[tata];
        
        fiu = tata;
        tata /= 2;
    }
    
    heap[fiu] = pnod;
    pos[pnod] = fiu;
}

int extrage_min()
{
    int minim = heap[1];
    heap[1] = heap[nheap]; pos[1] = pos[nheap];
    nheap--;
    move_down(1);
    return minim;
}

void move_down(int poz) // poz = pozitia in sirul heap;
{
    int tata = poz, fiu = poz * 2, pnod = heap[poz];
    
    while ( fiu <= nheap && (v[pnod] > v[fiu] && v[pnod] > v[fiu+1]) )
    {
        if (v[heap[fiu]] > v[heap[fiu+1]]) fiu++;
        
        heap[tata] = heap[fiu];
        pos[tata] = pos[fiu];
        
        tata = fiu;
        fiu *= 2;
    }
    
    heap[tata] = pnod;
    pos[pnod] = tata;
}

void dijkstra(int sursa, int dest)
{   
    int i, j, pas, k;
    
    for (i = 1; i <= N; i++) 
    {
	    if (i == sursa) continue;
	    dist[i] = INF, sel[i] = 0;
	    insert_heap(i);
    }
    
    for (PNOD p = L[sursa]; p; p=p->next)
    {
        dist[p->vf] = p->cost;
        move_up(p->vf);
    }
   
    sel[sursa] = 1;
    dist[sursa] = 0;
    
    for (pas = 1; pas < N; pas++)
    {
        k = extrage_min();
        sel[k] = 1;
        
        for (PNOD p = L[k]; p; p=p->next)
            if (dist[p->vf] > dist[k] + p->cost)
            {
                dist[p->vf] = dist[k] + p->cost;
                if (!pos[p->vf]) insert_heap(p->vf);
                else move_up(pos[p->vf]);
            }
   }
}