题意:给定一张无向图,每条边都有一个通过的概率 ,如果无法通过,那么就要回到起点重新出发
从起点到终点的时间固定为K,如果成功到达,又需要额外花费K的时间,问走S次的最小期望时间
题解:spfa+期望。先跑一遍spfa,找出从0到n-1的最大成功概率
设期望值为E,成功概率为p,如果成功,期望值为p*2k,如果不成功,期望值为(1-p)*(E+2k)
因此E=p*2k+(1-p)*(E+2k),化简为E=2k/p
最后再乘上s
#include<bits/stdc++.h>
using namespace std;
const double eps = 1e-8;
const int MX = 105;
struct Edge{
int v,nxt;
double c;
}edge[MX*MX];
int head[MX],tot;
void add(int u,int v,double c){
edge[tot].v=v;
edge[tot].c=c;
edge[tot].nxt=head[u];
head[u]=tot++;
}
void init(){
memset(head,-1,sizeof(head));
tot=0;
}
double d[MX];
bool vis[MX];
void spfa(){
memset(vis,0,sizeof(vis));
memset(d,0,sizeof(d));
queue<int>q;
q.push(0);
vis[0]=1;
d[0]=1;
while(!q.empty()){
int u=q.front();q.pop();
vis[u]=0;
for(int i=head[u];~i;i=edge[i].nxt){
int v=edge[i].v;
double c=edge[i].c;
if(d[v]>=d[u]*c) continue;
d[v]=d[u]*c;
if(vis[v]) continue;
vis[v]=1;
q.push(v);
}
}
}
int main(){
int T,n,m,k,s;
scanf("%d",&T);
for(int cas=1;cas<=T;cas++){
init();
scanf("%d%d%d%d",&n,&m,&s,&k);
for(int i=0;i<m;i++){
int u,v,c;
scanf("%d%d%d",&u,&v,&c);
add(u,v,c/100.0);
add(v,u,c/100.0);
}
spfa();
double ans=2.0*s*k/d[n-1];
printf("Case %d: %.7f\n",cas,ans);
}
return 0;
}