概率dp light 1321
作者:互联网
题意:给定一张无向图,每条边都有一个通过的概率 ,如果无法通过,那么就要回到起点重新出发
从起点到终点的时间固定为K,如果成功到达,又需要额外花费K的时间,问走S次的最小期望时间
思路:这道题分为两部分,第一部分是求spfa,第二部分是通过得出的最大的概率的那条路算出答案;怎么算呢,通过最短路求出后,设期望值为E,成功概率为p,如果成功,期望值为p*2k,如果不成功,期望值为(1-p)*(E+2k)因此E=p*2k+(1-p)*(E+2k),化简为E=2k/p最后再乘上s
1 #include<cstdio> 2 #include<algorithm> 3 #include<math.h> 4 #include<string.h> 5 #include<queue> 6 using namespace std; 7 const int maxn=1e4+10; 8 const int inf=0x3f3f3f3f; 9 int head[maxn],num=-1; 10 int s,t; 11 double dis[maxn];int vis[maxn]; 12 struct node 13 { 14 int v,next; 15 double w; 16 }G[maxn]; 17 void build(int u,int v,double w) 18 { 19 G[++num].v=v;G[num].w=w;G[num].next=head[u];head[u]=num; 20 G[++num].v=u;G[num].w=w;G[num].next=head[v];head[v]=num; 21 } 22 void init() 23 { 24 memset(head,-1,sizeof(head)); 25 num=-1; 26 } 27 void SPFA() 28 { 29 memset(dis,0,sizeof(dis)); 30 dis[0]=1; 31 queue<int>q; 32 q.push(0); 33 vis[0]=1; 34 while(!q.empty()){ 35 // printf("11111111111111111111111111\n"); 36 int u=q.front(); 37 q.pop(); 38 vis[u]=0; 39 for(int i=head[u];i!=-1;i=G[i].next){ 40 int v=G[i].v;double w=G[i].w; 41 if(dis[v]<dis[u]*w){ 42 dis[v]=dis[u]*w; 43 if(!vis[v]){ 44 q.push(v); 45 vis[v]=1; 46 } 47 } 48 } 49 } 50 } 51 int main() 52 { 53 int T; 54 scanf("%d",&T); 55 int cnt=0; 56 while(T--){ 57 init(); 58 int n,m,s,k; 59 scanf("%d%d%d%d",&n,&m,&s,&k); 60 for(int i=1;i<=m;i++){ 61 int u,v;double w; 62 scanf("%d%d%lf",&u,&v,&w); 63 w=w/100; 64 build(u,v,w); 65 } 66 SPFA(); 67 double ans=dis[n-1]; 68 double tmp=1.0/ans; 69 tmp=(double)(tmp*2*k*s); 70 printf("Case %d: %lf\n",++cnt,tmp); 71 } 72 return 0; 73 }
标签:head,1321,int,light,num,include,2k,dp,dis 来源: https://www.cnblogs.com/pangbi/p/11609744.html