原题传送门
练一练期望
这应该是一道期望dp入门题
首先发现图可以用拓扑处理出来,不用dfs的原因是怕常数大
然后做期望dp
以前没练过期望,今天终于懂了
期望=概率*值
而概率是没有单位的,所以期望与那个实际的值的单位是一样的
d
p
[
u
]
dp[u]
dp[u]表示
u
−
>
n
u->n
u−>n的期望长度
因为从1走到n,考虑从n倒推
转移方程:
d
p
[
v
]
+
=
(
d
p
[
u
]
+
d
i
s
(
u
,
v
)
)
/
d
e
g
[
v
]
dp[v]+=(dp[u]+dis(u,v))/deg[v]
dp[v]+=(dp[u]+dis(u,v))/deg[v](反向存图后,v是u的儿子,deg表示度,根据题意来的)
边界:
d
p
[
n
]
=
0
dp[n]=0
dp[n]=0
边DP边拓扑好了
Code:
#include <bits/stdc++.h>
#define maxn 100010
using namespace std;
struct Edge{
int to, next, len;
}edge[maxn << 1];
int n, m, num, head[maxn], in[maxn], deg[maxn];
double dp[maxn];
inline int read(){
int s = 0, w = 1;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
return s * w;
}
void addedge(int x, int y, int z){ edge[++num].to = y, edge[num].len = z, edge[num].next = head[x], head[x] = num; }
void dfs(){
queue <int> q;
q.push(n);
while (!q.empty()){
int u = q.front();
q.pop();
for (int i = head[u]; i; i = edge[i].next){
int v = edge[i].to;
dp[v] += (dp[u] + edge[i].len) / deg[v];
if (!--in[v]) q.push(v);
}
}
}
int main(){
n = read(), m = read();
for (int i = 1; i <= m; ++i){
int x = read(), y = read(), z = read();
addedge(y, x, z);
++in[x], ++deg[x];
}
dfs();
printf("%.2f\n", dp[1]);
return 0;
}

3132

被折叠的 条评论
为什么被折叠?



