Cod sursa(job #633230)

Utilizator blue_phoenixPosea Elena blue_phoenix Data 13 noiembrie 2011 12:18:56
Problema Algoritmul lui Dijkstra Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 2.59 kb
#include <vector>
#include <cstdio>
using namespace std;

#define MAXN 50005
const int INF=1<<30;

struct nod{
  int nod,cost;
};

vector <nod> lista[MAXN];
int dist[MAXN];
int heap[MAXN],k;//k este nr de noduri din heap
int poz[MAXN];//-1 daca a trecut prin heap , indicele locului in heap daca este deja in heap



void urca(int loc){
   int x;
   int aux;
   while((x=loc/2) && dist[heap[loc]]<dist[heap[x]]){
      //interschimb nodul de pe locul loc cu tatal sau
      poz[heap[x]]=loc;
      poz[heap[loc]]=x;
      aux=heap[loc];
      heap[loc]=heap[x];
      heap[x]=aux;
      loc=x;
   }
}

void coboara(int loc){
   //cobor in fiul cel mai mic dintre cei doi
    int aux, x, y = 0;
    while (loc != y){
	y = loc;
	if ((x=y*2)<=k && dist[heap[loc]]>dist[heap[x]]) loc = x;
        x++;
	if (x<=k && dist[heap[loc]]>dist[heap[x]]) loc = x;
          aux = heap[loc];
	  heap[loc] = heap[y];
	  heap[y] = aux;
          poz[heap[loc]] = loc;
	  poz[heap[y]] = y;
	}
}

int main(){
  FILE *fin=fopen("dijkstra.in","r");
  FILE *fout=fopen("dijkstra.out","w");
  int N,M,a,b,c;
  fscanf(fin,"%d%d",&N,&M);
  int i;
  nod aux;
  for(i=0;i<M;i++){
     fscanf(fin,"%d%d%d",&a,&b,&c);
     aux.nod=b;
     aux.cost=c;
     lista[a].push_back(aux);
  }
  //final citire
  //initializari
    for(i=2;i<=N;i++){
      dist[i]=INF;
      poz[i]=-1;//nu sunt in heap
    
    }
    dist[1]=0;
    poz[1]=1;
  k=1;//cate noduri sunt in heap
    //adaug sursa in heap
    heap[1]=1;
  int min;
    while(k){//cat timp heapul nu e vid
       min=heap[1];//e min-heap; tine doar noduri nevizitate in el
      //scot varful heapului....
       heap[1]=heap[k];
       poz[heap[1]]=1;
       k--;
       coboara(1);
       //heap tine indicii nodurilor 
       for(i=0;i<lista[min].size();i++){
           //daca valoarea nodului lista[min][i] se poate imbunatati prin nodul min
           if(dist[lista[min][i].nod]>dist[min]+lista[min][i].cost){
                 dist[lista[min][i].nod]=dist[min]+lista[min][i].cost;
                 //am imbunatatit val nodului lista[min][i]
                 if(poz[lista[min][i].nod]!=-1){
                    //e deja in heap, doar ca acum are alta valoare, mai mica
                    //trebuie urcat in heap
                    urca(poz[lista[min][i].nod]);
                 }else{
                    //nu e in heap, trebuie adaugat
                    heap[++k]=lista[min][i].nod;
                    poz[heap[k]]=k;
                    urca(k);
                 }
           }
       }
    }
    for(i=2;i<=N;i++){
       fprintf(fout,"%d ",(dist[i]==INF?0:dist[i]));
    }
  fprintf(fout,"\n");

return 0;
}