Cod sursa(job #140864)

Utilizator nicolaetitus12Nicolae Titus nicolaetitus12 Data 22 februarie 2008 13:13:42
Problema Distante Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.08 kb
//1-contoare,
#include <string.h>
#include <stdio.h>
#define INF 20000
#define M 100000
#define N 50000
long muc[2*M+2][3];
long mp[N+1],varf;
long mmin[132000][2];
FILE *fin,*fout;

long n,m;
long cost[N+1],costi[N+1];


void dij(long gnod)
{long pl;
 long i,j,a,b,imin;
 for (a=n,b=0;a;a/=2,b++);
 b=1<<b;
 for (i=1;i<2*b;i++)
 {mmin[i][0]=INF;}
 
 for (i=b,j=1;i<2*b;i++,j++)
 {mmin[i][1]=j;} 
 
 mmin[b-1+gnod][0]=0;
 for (i=b-1+gnod;i/2;i/=2)
 {if(mmin[i/2][0]>mmin[i][0])
  {mmin[i/2][0]=mmin[i][0];
   mmin[i/2][1]=mmin[i][1];
  }
 }
 cost[gnod]=0;


 for (i=0;i<n-1;i++)
 {imin=mmin[1][1];
  mmin[b-1+imin][0]=INF;
  for (j=(b-1+imin)/2;j;j/=2)
  {if(mmin[2*j][0]>mmin[2*j+1][0])
   {mmin[j][0]=mmin[2*j+1][0];
    mmin[j][1]=mmin[2*j+1][1];
   }
   else
   {mmin[j][0]=mmin[2*j][0];
    mmin[j][1]=mmin[2*j][1];
   }
  }
  for(pl=mp[imin];pl!=0;pl=muc[pl][2])
  {if(cost[muc[pl][0]]>cost[imin]+muc[pl][1])
   {cost[muc[pl][0]]=cost[imin]+muc[pl][1];
    mmin[b-1+muc[pl][0]][0]=cost[muc[pl][0]];
    for (j=b-1+muc[pl][0];j/2;j/=2)
    {if(mmin[j/2][0]>mmin[j][0])
     {mmin[j/2][0]=mmin[j][0];
      mmin[j/2][1]=mmin[j][1];
     }
    }
   }

  }
 }
}
long compar()
{long i,flag=1;
 for (i=1;i<=n;i++)
 {if(costi[i]!=cost[i])
  {flag=0;break;}
 }
 if(flag)
 {return 1;}
 else 
  return 0;
}


void citire()
{long i,a,b,c,s;
 fscanf(fin,"%ld%ld%ld",&n,&m,&s);
 memset(mp,0,sizeof(mp));
 memset(muc,0,sizeof(muc));
 varf=1;
 for (i=1;i<=n;i++)
 {fscanf(fin,"%ld",&costi[i]);
 }
 for (i=0;i<m;i++)
 {fscanf(fin,"%ld%ld%ld",&a,&b,&c);
  muc[varf][0]=b;
  muc[varf][1]=c;
  muc[varf][2]=mp[a];
  mp[a]=varf;
  varf++;

  muc[varf][0]=a;
  muc[varf][1]=c;
  muc[varf][2]=mp[b];
  mp[b]=varf;
  varf++;
 }
 for (i=1;i<=n;i++)
 {cost[i]=INF;}

 dij(s);

 if(compar())
 fprintf(fout,"DA\n");

 else 
 fprintf(fout,"NU\n");
}

int main ()
{varf=1;
 long i,t;
 fin=fopen("distante.in","r");
 fout=fopen("distante.out","w");
 fscanf(fin,"%ld",&t);
 for (i=0;i<t;i++)
 {citire();
 }
 fclose(fout);
 return 0;
}