CF605E
阿新 • • 發佈:2020-07-08
https://www.cnblogs.com/cjyyb/p/9707853.html
https://www.cnblogs.com/daklqw/p/12009106.html
每次應該找出邊中期望天數\(E(x)\)儘量小的走過去
假設找出了一個排列\(P\)使得\(E(P_i)\)隨\(i\)單調不降
\[E(P_i)=\dfrac{\sum_{j<i} E(P_j)\times p_{P_i,P_j}\prod_{k<j}(1−p_{P_i,P_k})}{1-\prod_{j<i}p_{P_i,P_j}} \]
除掉\(1-\prod p\)是因為有這個概率所有邊都走不了所以只能停留在原地
大概是類似dij一樣每次取出\(E(x)\)
#include<bits/stdc++.h> using namespace std; #define fp(i,l,r) for(register int (i)=(l);i<=(r);++(i)) #define fd(i,l,r) for(register int (i)=(l);i>=(r);--(i)) #define fe(i,u) for(register int (i)=front[(u)];(i);(i)=e[(i)].next) #define mem(a) memset((a),0,sizeof (a)) #define O(x) cerr<<#x<<':'<<x<<endl #define prev pku inline int read(){ int x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); return x*f; } void wr(int x){ if(x<0)putchar('-'),x=-x; if(x>=10)wr(x/10); putchar('0'+x%10); } const int MAXN=1e3+10; double P[MAXN][MAXN]; double dis[MAXN],prod[MAXN],tmp[MAXN];bool vis[MAXN]; int n; main(){ n=read(); fp(i,1,n)fp(j,1,n)P[i][j]=1.0*read()/100.0; fp(i,0,n-1)dis[i]=1e100,tmp[i]=prod[i]=1; fp(i,1,n){ int u=0; fp(j,1,n)if(!vis[j]&&dis[u]>dis[j])u=j; if(u==1){printf("%.10lf\n",dis[1]);return 0;} vis[u]=1; fp(v,1,n)if(!vis[v]){ tmp[v]+=dis[u]*prod[v]*P[v][u]; prod[v]*=1-P[v][u]; dis[v]=tmp[v]/(1-prod[v]); } } return 1; }