Cod sursa(job #203398)

Utilizator nicolaetitus12Nicolae Titus nicolaetitus12 Data 16 august 2008 00:46:38
Problema Algoritmul lui Dijkstra Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2 kb
#include <stdio.h>
#define N 50001
#define M 250001
#define st(x) 2*(x)
#define dr(x) 2*(x)+1
#define pr(x) (x)/2
long n,m;
long p[N];
struct vecin
{long cost;
 long urm;
 long nod;
}v[2*M];
long vv;

struct heap
{long nod;
 long cost;
}h[N];
long vh;

long pheap[N];
long cost[N];
int flagn[N];
int flagf[N];

void adauga_muchie(long a,long b,long c)
{vv++;
 v[vv].urm=p[a];
 p[a]=vv;
 v[vv].nod=b;
 v[vv].cost=c;
}
void interschimba (long a,long b)
{heap aux;
 aux=h[a];h[a]=h[b];h[b]=aux;
 pheap[h[a].nod]=a;
 pheap[h[b].nod]=b;
}
void adauga_heap(long nod,long cost)
{vh++;
 long i;
 struct heap aux;
 h[vh].nod=nod;
 h[vh].cost=cost;
 for (i=vh;h[i].cost<h[pr(i)].cost&&pr(i);i=pr(i))
 {interschimba(i,pr(i));
 }

}

void adauga_vecini(long a)
{long q,i;
 heap aux;
 for (q=p[a];q;q=v[q].urm)
 {if(flagf[v[q].nod]==0)
  {if(flagn[v[q].nod]==0)
   {adauga_heap(v[q].nod,v[q].cost+cost[a]);
    flagf[v[q].nod]=1;
   }
  }
  else
  {if(h[pheap[v[q].nod]].cost>cost[a]+v[q].cost)
   {h[pheap[v[q].nod]].cost=cost[a]+v[q].cost;
    for (i=pheap[v[q].nod];h[i].cost<h[pr(i)].cost&&pr(i);i=pr(i))
    {interschimba(i,pr(i));
    }
   }
  }
 }
}

void sift(long k)
{long min=k;
 heap aux;
 if(st(k)<=vh&&h[st(k)].cost<h[k].cost)
 {min=st(k);
 }
 if(dr(k)<=vh&&h[dr(k)].cost<h[min].cost)
 {min=dr(k);
 }
 if(min!=k)
 {interschimba(k,min);
  sift(min);
 }
 
}

void scoate_minim()
{pheap[h[1].nod]=0;
 h[1]=h[vh];
 pheap[h[1].nod]=1;
 vh--;
 sift(1);
}

int main ()
{long a,b,c,i;
 heap min;
 freopen("dijkstra.in","r",stdin);
 freopen("dijkstra.out","w",stdout);
 scanf("%ld%ld",&n,&m);
 for (vv=0,i=1;i<=m;i++)
 {scanf("%ld%ld%ld",&a,&b,&c);
  adauga_muchie(a,b,c);
 }

 flagn[1]=1;
 cost[1]=0;
 adauga_vecini(1);
 for (i=1;i<n;i++)
 {min=h[1];
  cost[min.nod]=min.cost;
  flagf[min.nod]=0;
  flagn[min.nod]=1;
  scoate_minim();
  adauga_vecini(min.nod);
 }
 
 for (i=2;i<=n;i++)
 {printf("%ld ",cost[i]);
 }
 
 return 0;
}