Cod sursa(job #109838)

Utilizator VmanDuta Vlad Vman Data 25 noiembrie 2007 12:48:05
Problema Tunelul groazei Scor 0
Compilator cpp Status done
Runda preONI 2008, Runda 1, Clasele 11-12 Marime 1.35 kb
using namespace std;
#include <stdio.h>
#include <vector>

#define Nmax 256
#define Lmax 524288
#define pmin 0.0000001

int N,M,A,B,C,i;
int q[Lmax],d[Lmax],st,dr;
double p[Lmax],m,mp;
vector<int> g[Nmax];
vector<int> c[Nmax];

void solve()
{
 double pp;
 int i,sz,left=0,right=0;
 //initializari
 q[st=dr=0]=1;
 p[0]=1.0;
 d[0]=0;
 while (left<=right)
       {
        if (q[st]==N) { mp+=p[st];m+=double(p[st]*d[st]);st=(st+1)&(Lmax-1);++left;continue; }
        //probabilitatea curenta
        pp=double(p[st]/g[q[st]].size());
        sz=g[q[st]].size();
        //avanseaza
        if (pp>pmin)
           for (i=0;i<sz;++i)
               {
                ++right;
                dr=(dr+1)&(Lmax-1);
                q[dr]=g[q[st]][i];
                p[dr]=pp;
                d[dr]=d[st]+c[q[st]][i];
               }
        //urmatorul element in coada
        st=(st+1)&(Lmax-1);
        ++left;
       }
}

int main()
{
 freopen("tunel.in","r",stdin);
 freopen("tunel.out","w",stdout);
 scanf("%d %d",&N,&M);
 for (i=0;i<M;++i)
     {
      scanf("%d %d %d",&A,&B,&C);
      g[A].push_back(B);
      g[B].push_back(A);
      c[A].push_back(C);
      c[B].push_back(C);
     }
 solve();
 if (double(1-mp)>0.0001) m+=double(d[dr]*(1-mp))-0.051;
 printf("%.3lf",m);
 fclose(stdout);
 fclose(stdin);
 return 0;
}