洛谷 P4316绿豆蛙的归宿
记f[i]表示经过i号点的概率。
那么点v从点u到达的概率=经过点u的概率/点u的出度。由于v可以由多个点走到,所以f[v]+=f[u]/out[u]。
计算f的过程可以在拓扑中完成,同时可以记录走过这条边的期望,相加就是答案。
#include<complex> #include<cstdio> using namespace std; const int N=1e5+7; struct node{ int v,w,nxt; }e[N<<1]; int n,m,Enum; double ans; int front[N],in[N],out[N]; double f[N]; int q[N],tail,head=1; int qread() { int x=0; char ch=getchar(); while(ch<'0' || ch>'9')ch=getchar(); while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} return x; } void Insert(int u,int v,int w) { e[++Enum].v=v; e[Enum].w=w; e[Enum].nxt=front[u]; front[u]=Enum; } int main() { scanf("%d%d",&n,&m); int u,v,w; for(int i=1;i<=m;i++) { u=qread();v=qread();w=qread(); Insert(u,v,w); out[u]++;in[v]++; } f[1]=1; q[++tail]=1; while(head<=tail) { u=q[head++]; for(int i=front[u];i;i=e[i].nxt) { v=e[i].v; f[v]+=1.0*f[u]/out[u]; ans+=1.0*f[u]/out[u]*e[i].w; in[v]--; if(!in[v])q[++tail]=v; } } printf("%.2lf\n",ans); return 0; }