题目链接:https://nanti.jisuanke.com/t/41301
题意:N个点M条边的有向无环图,1为唯一入度为0的点,N为唯一出度为0的点,现在你从1号点出发,每单位时间,你有相同的概率,走向下一节点或原地不动。第 i 单位时间内你的消耗为 i ,询问你走到 N 点的期望消耗。
题解:
d[i]为i点到n点的期望天数
dp[i] 为i点到n点的能量消耗期望
#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;
}