题目:https://www.luogu.org/problemnew/show/P4316
期望水题,从终点向起点推,因为是DAG,所以拓扑序推过去即可。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; queue<int>q; int const maxn=1e5+5,maxm=2*maxn; int n,m,rd[maxn],cd[maxn],d[maxn],head[maxn],ct; double p[maxn]; struct N{ int to,next,w; N(int t=0,int n=0,int w=0):to(t),next(n),w(w) {} }edge[maxm]; int main() { scanf("%d%d",&n,&m); for(int i=1,x,y,z;i<=m;i++) { scanf("%d%d%d",&x,&y,&z); edge[++ct]=N(x,head[y],z);head[y]=ct;//反向连边 cd[y]++;rd[x]++;d[x]++; } for(int i=1;i<=n;i++) if(!rd[i])q.push(i); while(q.size()) { int x=q.front();q.pop(); for(int i=head[x],u;i;i=edge[i].next) { p[u=edge[i].to]+=1.0/d[u]*(p[x]+edge[i].w); // printf("x=%d u=%d p[%d]=%.2lf ",x,u,u,p[u]); rd[u]--; if(!rd[u])q.push(u); } } for(int i=1;i<=n;i++) if(!cd[i]) { printf("%.2lf ",p[i]); return 0; } }