Cod sursa(job #723250)

Utilizator BlaugranasEnal Gemaledin Blaugranas Data 25 martie 2012 10:26:53
Problema Drumuri minime Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.56 kb
#include<cstdio>
#include<cmath>
const int P=104659,N=1501,M=1<<30;
const double E=1e-10;
struct graf
{int nod;
double cost;
graf *next;};
int n,m,h[N],p[N],k,b[N],x,y,i,min;
graf *a[N],*q;
double d[N],z;

void add(int e,int b,double c)
{graf *q=new graf;
q->nod=b,q->cost=c,q->next=a[e],a[e]=q;}

void swap(int x,int y)
{int t=h[x];
h[x]=h[y],h[y]=t;}

void upheap(int b)
{int t;
while(b>1)
    {t=b>>1;
    if(d[h[t]]-d[h[b]]>E)
         p[h[b]]=t,p[h[t]]=b,swap(t,b),b=t;
    else
         b=1;}}

void downheap(int b)
{int f;
while(b<=k)
    {f=b;
    if((b<<1)<=k)
         {f=b<<1;
         if(f<k&&d[h[f+1]]-d[h[f]]<E)
               ++f;}
    else
         return;
    if(d[h[b]]-d[h[f]]>E)
         p[h[b]]=f,p[h[f]]=b,swap(b,f),b=f;
    else
         return;}}

int main()
{FILE *in=fopen("dmin.in","r"),*out=fopen("dmin.out","w");
fscanf(in,"%d%d",&n,&m);
while(m--)
    fscanf(in,"%d%d%lf",&x,&y,&z),add(x,y,log(z)),add(y,x,log(z));
for(i=2;i<=n;++i)
    d[i]=M,p[i]=-1;
p[1]=h[++k]=b[1]=1,d[1]=1.0;
while(k)
    {min=h[1],swap(1,k--),p[h[1]]=1,downheap(1);
    for(q=a[min];q;q=q->next)
    if(d[q->nod]-d[min]-q->cost>E)
         {d[q->nod]=d[min]+q->cost,b[q->nod]=b[min];
         if(p[q->nod]!=-1)
               upheap(p[q->nod]);
         else
               h[++k]=q->nod,p[h[k]]=k,upheap(k);}
    else
         if(fabs(d[q->nod]-d[min]-q->cost)<=E)
               {b[q->nod]+=b[min];
               if(b[q->nod]>P)
                     b[q->nod]-=P;}}
for(i=2;i<=n;++i)
    fprintf(out,"%d ",b[i]);
return 0;}