3146 绿豆蛙的归宿
随着新版百度空间的下线,Blog宠物绿豆蛙完成了它的使命,去寻找它新的归宿。
给出一个有向无环的连通图,起点为11终点为nn,每条边都有一个长度。绿豆蛙从起点出发,走向终点。
到达每一个顶点时,如果有K条离开该点的道路,绿豆蛙可以选择任意一条道路离开该点,并且走向每条路的概率为。
现在绿豆蛙想知道,从起点走到终点的所经过的路径总长度期望是多少?
输入
第一行两个整数n,m表示图中有n个点m条边
第二行到第m+1行,每行3个整数a b c,表示有一条从a到b长度为c的有向边
输出
一行一个数,表示从起点到终点路径总长度的期望值,四舍五入保留两位小数
数据范围
20% 2 <= n <= 100 2 <= m <= 150
40% 2 <= n <= 1000 2 <= m <= 2000
100% 2 <= n <= 100000 2 <= m <= 199996
输入样例
输入样例1:
4 4
1 2 1
1 3 2
2 3 3
3 4 4
输出样例
输出样例1:
7.00
解析:
f[i]表示到终点n的期望长度。
f[n]=0
f[i]=(f[j]+e[i].w)/k[i],i-->j,k[i]是i的出度。
拓扑排序+期望DP
放代码:
#include<bits/stdc++.h>
#define mod 1000003
#define inf 10000000
typedef long long ll;
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
double f[100005];
int Next[200005],ret[200005],Head[100005],len[200005];
int n,m,tot,du[100005];
bool vis[100005];
inline void ins(int u,int v,int l)
{
ret[++tot]=v;len[tot]=l;
Next[tot]=Head[u];Head[u]=tot;
}
void dfs(int u)
{
if (vis[u]) return;
vis[u]=1;
for (int i=Head[u];i;i=Next[i])
{
dfs(ret[i]);
f[u]+=f[ret[i]]+len[i];
}
if (du[u]) f[u]/=du[u];
}
int main()
{
n=read();m=read();
for (int i=1;i<=m;i++)
{
int u=read(),v=read(),l=read();
ins(u,v,l);
du[u]++;
}
dfs(1);
printf("%.2lf",f[1]);
return 0;
}