BZOJ3036: 绿豆蛙的归宿
3036: 绿豆蛙的归宿
Time Limit: 2 Sec Memory Limit: 128 MBSubmit: 362 Solved: 255
[Submit][Status][Discuss]
Description
随着新版百度空间的下线,Blog宠物绿豆蛙完成了它的使命,去寻找它新的归宿。
给出一个有向无环的连通图,起点为1终点为N,每条边都有一个长度。绿豆蛙从起点出发,走向终点。
到达每一个顶点时,如果有K条离开该点的道路,绿豆蛙可以选择任意一条道路离开该点,并且走向每条路的概率为 1/K 。
现在绿豆蛙想知道,从起点走到终点的所经过的路径总长度期望是多少?
Input
第一行: 两个整数 N M,代表图中有N个点、M条边
第二行到第 1+M 行: 每行3个整数 a b c,代表从a到b有一条长度为c的有向边
Output
从起点到终点路径总长度的期望值,四舍五入保留两位小数。
Sample Input
4 4
1 2 1
1 3 2
2 3 3
3 4 4
1 2 1
1 3 2
2 3 3
3 4 4
Sample Output
7.00
HINT
对于100%的数据 N<=100000,M<=2*N
Source
题解:水题我爱刷!
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<cmath> #define ll long long #define N 100005 #define M 200005 using namespace std; int d[N]; int pre[M],now[N],v[M],val[M]; double f[N]; bool vis[N]; int n,m,tot; int read() { int x=0,f=1; char ch; while (ch=getchar(),ch<'0'||ch>'9') if (ch=='-') f=-1; while (x=x*10+ch-'0',ch=getchar(),ch>='0'&&ch<='9'); return x*f; } void ins(int a,int b,int c) { ++tot; pre[tot]=now[a]; now[a]=tot; v[tot]=b; val[tot]=c; } void solve(int x,int fa) { if (!vis[x]) vis[x]=1; else return ; for (int p=now[x]; p; p=pre[p]) { int son=v[p]; if (son==fa) continue; solve(son,x); f[x]+=val[p]+f[son]; } if (d[x]) f[x]=1.0*f[x]/d[x]; } int main() { n=read(); m=read(); for (int i=1; i<=m; i++) { int u=read(),v=read(),val=read(); ins(u,v,val); d[u]++; } solve(1,0); printf("%0.2lf",f[1]); }
我太蒟蒻了,所以神犇们留下意见让我跪膜