洛谷 P4316 绿豆蛙的归宿(期望)
传送门
解题思路
首先答案很显然:
\[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;
}