洛谷 P4316 綠豆蛙的歸宿(期望)
阿新 • • 發佈:2021-06-12
傳送門
解題思路
首先答案很顯然:
\[ans=\sum_{i=1}^{n}(p[i]\times to[i]) \]其中 \(p[i]\) 表示到點 \(i\) 的概率,\(to[i]\) 表示 \(i\) 的出邊的邊權和。
\(to[i]\) 可以預處理得到,而 \(p[i]\) 可以在反圖上 dfs 一遍得到。
//翹歷史課真爽
AC程式碼
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const int maxn=1e5+5; int n,m,to[maxn],num[maxn],p[maxn],cnt; double ans,pre[maxn]; struct node{ int v,next; }e[maxn*2]; void insert(int u,int v){ cnt++; e[cnt].v=v; e[cnt].next=p[u]; p[u]=cnt; } void dfs(int u){ for(int i=p[u];i!=-1;i=e[i].next){ if(!pre[e[i].v]) dfs(e[i].v); pre[u]+=pre[e[i].v]; } pre[u]=pre[u]/num[u]; } int main(){ memset(p,-1,sizeof(p)); cin>>n>>m; for(int i=1;i<=m;i++){ int u,v,w; scanf("%d%d%d",&u,&v,&w); to[u]+=w; num[u]++; insert(v,u); } num[n]=1; pre[1]=1.0/num[1]; dfs(n); for(int i=1;i<=n;i++) ans+=to[i]*pre[i]; printf("%0.2lf",ans); return 0; }