Cod sursa(job #298768)

Utilizator drag0shSandulescu Dragos drag0sh Data 6 aprilie 2009 13:00:25
Problema PScNv Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.84 kb
#include <stdio.h>
#define maxn 250005
#define oo 0x3f3f3f
FILE *in=fopen("pscnv.in","r"),*out=fopen("pscnv.out","w");


struct graf{
  int nod,cost;
  graf*adr_urm;
  
};

graf *a[maxn];
int n,d[maxn],h[maxn],poz[maxn],source,dest,k;

void adauga(int where,int what,int cost){
  graf *p=new graf;
  p->nod=what;
  p->cost=cost;
  p->adr_urm=a[where];
  a[where]=p;
}

void citire(){
  int m,x,y,z;
  fscanf(in,"%d%d%d%d",&n,&m,&source,&dest);
  while(m--){
    fscanf(in,"%d%d%d",&x,&y,&z);
    adauga(x,y,z);
  }
}

void swap(int a,int b){
  int  aux=h[a];
  h[a]=h[b];
  h[b]=aux;
}

void downheap(int what){
  int son;
  son=1;
  while(son){
    son=0;
    if((what<<1)<=k){
      son=what<<1;
      if(son+1<=k&&d[h[son+1]]<d[h[son]])son++;
      if(d[h[son]]>=d[h[what]])son=0;
    }
    if(son){
      swap(what,son);
      poz[h[what]]=what;
      poz[h[son]]=son;
      what=son; 
    }
  }
}

int maxim(int a,int b){
  if(a>b)return a;
  else return b;
}

void upheap(int what){
  while(what>1&&(d[h[what>>1]]>d[h[what]])){
    swap(what,what>>1);
    poz[h[what]]=what;
    poz[h[what>>1]]=what>>1;
    what>>=1;
  }
}


void djskstra_heap(){
  for(int i=1;i<=n;i++)d[i]=oo,poz[i]=-1;
  d[source]=0;
  poz[source]=1;
  h[++k]=source;
  while(k){
    int min=h[1],elem;
    swap(1,k);
    poz[h[1]]=1;
    k--;
    // printf("(%d)",min);
    downheap(1);
    graf *p= a[min];
    while(p){
      elem=d[min]>(p->cost)? d[min] :(p->cost);
      if(d[p->nod]>elem){
	d[p->nod]=elem;
	if(poz[p->nod]!=-1)
	  upheap(poz[p->nod]);
	else{
	  h[++k]=p->nod;
	  poz[h[k]]=k;
	  upheap(k);
	}

      }
      p=p->adr_urm;
    }
  }
}





int main(){
  
  citire();
  djskstra_heap();
  //   for ( int i = 1; i <= n; ++i )      
  //   fprintf(out, "%d ", d[i] == oo ? 0 : d[i]);       fprintf(out, "\n");   
    fprintf(out,"%d",d[dest]);
  
  fclose(in);
  fclose(out);
  return 0;
}