LightOJ 1287 Where to Run(期望)

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1287

题意:给定一个n个点的无向图(0到n-1),你开始在0。你开始遍历这个图,每个点只能被遍历一次。当你在某个点u时,假设u可以到达v1,v2且到达v1或者v2后均可以将其他未遍历的点遍历完,则你在u有三种选择:1、在u再呆5分钟;2、去v1,;3、去v2。概率均为1/3。求遍历完整个图的时间期望。

思路:f[u]=(5+f[u])/(x+1)+(g[u][vi]+f[vi])/(x+1),1<=i<=x,x为合法的下一个点。。

 

View Code 

 #include <iostream>

 #include <cstdio>

 #include <cstring>

 using namespace std;

 

 

 

 const int INF=1000000000;

 int C,num=0;

 int n,m,g[15][15];

 double f[15][1<<15];

 bool visit[15][1<<15];

 

 

 

 int DFS(int st,int u)

 {

     if(st==(1<<n)-1)

     {

         f[u][st]=0;

         return 1;

     }

     if(visit[u][st]) return f[u][st]>1e-10;

     visit[u][st]=1;

     f[u][st]=5;

     int i,st0,cnt=0;

     for(i=0;i<n;i++) if(!(st&(1<<i))&&g[u][i]!=INF&&DFS(st|(1<<i),i))

     {

         st0=st|(1<<i);

         f[u][st]+=g[u][i]+f[i][st0];

         cnt++;

     }

     if(!cnt)

     {

         f[u][st]=0;

         return 0;

     }

     f[u][st]/=cnt;

     return 1;

 }

 

 int main()

 {

     for(scanf("%d",&C);C--;)

     {

         scanf("%d%d",&n,&m);

         int i,j,u,v,w;

         for(i=0;i<n;i++) for(j=0;j<n;j++) g[i][j]=INF;

         for(i=1;i<=m;i++)

         {

             scanf("%d%d%d",&u,&v,&w);

             g[u][v]=g[v][u]=w;

         }

         memset(visit,0,sizeof(visit));

         DFS(1,0);

         printf("Case %d: %.6lf\n",++num,f[0][1]);

     }

     return 0;

 }

 

  

 

 

 

你可能感兴趣的:(where)