洛谷 P4316 绿豆蛙的归宿(期望)

传送门


解题思路

首先答案很显然:

[ans=sum_{i=1}^{n}(p[i] imes 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;
}
原文地址:https://www.cnblogs.com/yinyuqin/p/14878577.html