The Preliminary Contest for ICPC Asia Nanjing 2019

本文最后更新于:星期四, 二月 3日 2022, 9:15 晚上

D. Robots

题意:给定一个DAGDAG,机器人每次等概率的选择一个点走或者停留,每次花费是当前天数,求1n1\rightarrow n的花费期望

思路:fuf_u表示到uu的期望,那么很显然fu=fuoutu+1+fv+1f_u = \frac{f_u}{out_u + 1} + \sum f_v + 1gug_u表示花费期望,那么gu=guoutu+1+gv+fug_u=\frac{g_u}{out_u+1}+\sum g_v + f_u。看错题可还行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

#include <bits/stdc++.h>

using namespace std;

#define endl "\n"
using ll = long long;
using db = double;

const int N = 1e5 + 10;

int n, m;
db f[N], g[N];
int d1[N], d2[N], in[N], out[N];
vector<vector<int>> G;

void gao() {
queue<int> q;
q.push(n);
while (!q.empty()) {
int u = q.front();
q.pop();
if (out[u]) {
f[u] += out[u] + 1;
f[u] /= out[u];
}
for (auto v: G[u]) {
f[v] += f[u];
--d1[v];
if (d1[v] == 0) {
q.push(v);
}
}
}
q.push(n);
while (!q.empty()) {
int u = q.front();
q.pop();
if (out[u]) {
g[u] += f[u] * (out[u] + 1);
g[u] /= out[u];
}
for (auto v : G[u]) {
g[v] += g[u];
--d2[v];
if (d2[v] == 0) {
q.push(v);
}
}
}
}

void RUN() {
int _T;
scanf("%d", &_T);
while (_T--) {
scanf("%d %d", &n, &m);
G.clear();
G.resize(n + 1);
for (int i = 1; i <= n; ++i) {
f[i] = 0.0;
g[i] = 0.0;
d1[i] = 0;
d2[i] = 0;
in[i] = 0;
out[i] = 0;
}
for (int i = 1, u, v; i <= m; ++i) {
scanf("%d %d", &u, &v);
G[v].push_back(u);
d1[u]++;
d2[u]++;
out[u]++, in[v]++;
}
gao();
printf("%.2f\n", g[1]);
}
}

int main() {
#ifdef LOCAL_JUDGE
freopen("input.txt", "r", stdin);
#endif

ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);

RUN();

#ifdef LOCAL_JUDGE
cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
return 0;
}


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!