2019南京网络赛 D.Robots 树上期望dp

题目链接:https://nanti.jisuanke.com/t/41301

题意:N个点M条边的有向无环图,1为唯一入度为0的点,N为唯一出度为0的点,现在你从1号点出发,每单位时间,你有相同的概率,走向下一节点或原地不动。第 i 单位时间内你的消耗为 i ,询问你走到 N 点的期望消耗。

题解:

d[i]为i点到n点的期望天数

dp[i] 为i点到n点的能量消耗期望

d[u]=\frac{1}{size + 1} * d[u] + \sum\frac{1}{size + 1} * d[to] + 1 

dp[u]=\frac{1}{size + 1} * dp[u] + \sum\frac{1}{size + 1} * dp[to] + d[u]

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10; 
vector<int> v[N];
int a[N * 2], len;
int n, m;
double dp[N], d[N];
int in[N];
void dfs1(int u) {
	if(d[u] > 0) return;
	if(v[u].size() == 0) return;
	double cnt = 0;
	int to;
	for(int i = 0; i < v[u].size(); i++) {
		to = v[u][i];
		dfs1(to);
		cnt += d[to];
	}
	d[u] = (v[u].size() + cnt + 1) / v[u].size();
//	cout <<u << " " <<d[u] << endl;
}
void dfs2(int u) {
	if(dp[u] > 0) return;
	if(v[u].size() == 0) return;
	double cnt = 0;
	int to;
	for(int i = 0; i < v[u].size(); i++) {
		to = v[u][i];
		dfs2(to);
		cnt += dp[to];
	}
	dp[u] = (cnt + (v[u].size() + 1) * d[u]) / v[u].size();
}
int main() {
	int T;
	int x, y;
	scanf("%d", &T);
	while(T--) {
		len = 0;
		scanf("%d %d", &n, &m);
		for(int i = 1; i <= n; i++) {
			v[i].clear();
			d[i] = 0;
			dp[i] = 0;
		}
		for(int i = 1; i <= m; i++) {
			scanf("%d %d", &x, &y);
			v[x].push_back(y);
		}
		dfs1(1);
		dfs2(1);
		printf("%.2f\n", dp[1]);
	}
	return 0;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值