1. 程式人生 > 其它 >洛谷 P4316 綠豆蛙的歸宿(期望)

洛谷 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;
}