洛谷传送门
【题目分析】
受收集邮票这道题的影响,定义ans[x]表示从节点x到终点的期望路径长度。
分析一下很容易能得出ans[x]的递推式:
,其中out[x]表示离开x的边的数量。
所以直接建一个从终点到起点的反图,一边建一边统计答案即可,答案就是ans[1]
【代码~】
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+10;
const int MAXM=2e5+10;
int n,m,cnt;
int head[MAXN],du[MAXN],chu[MAXN];
double ans[MAXN];
int nxt[MAXM],to[MAXM],w[MAXM];
int Read(){
int i=0,f=1;
char c;
for(c=getchar();(c>'9'||c<'0')&&c!='-';c=getchar());
if(c=='-')
f=-1,c=getchar();
for(;c>='0'&&c<='9';c=getchar())
i=(i<<3)+(i<<1)+c-'0';
return i*f;
}
void add(int x,int y,int z){
nxt[cnt]=head[x];
head[x]=cnt;
to[cnt]=y;
w[cnt]=z;
++cnt;
}
void topsort(){
queue<int> q;
for(int i=1;i<=n;++i){
if(!du[i])
q.push(i);
}
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=head[u];i!=-1;i=nxt[i]){
int v=to[i];
ans[v]+=1.0*(ans[u]+w[i])/chu[v];
--du[v];
if(!du[v])
q.push(v);
}
}
}
int main(){
memset(head,-1,sizeof(head));
n=Read(),m=Read();
for(int i=1;i<=m;++i){
int x=Read(),y=Read(),z=Read();
add(y,x,z);
++du[x];
++chu[x];
}
topsort();
printf("%.2lf",ans[1]);
return 0;
}