#include using namespace std; const int N = 1e5 + 10, M = 2 * N; //邻接表 int h[N], e[M], ne[M], w[M], idx; void add(int a, int b, int c) { e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++; } int n, m; // n个顶点,m条边 int out[N], in[N]; //出度,入度 double f[N], g[N]; // f:数学期望结果 g:概率 void topsort() { queue q; //起点为1,起点的概率为100% q.push(1); g[1] = 1.0; f[1] = 0.0; // DAG,执行拓扑序,以保证计算的顺序正确,确保递归过程中,前序数据都已处理完毕 while (q.size()) { auto u = q.front(); q.pop(); for (int i = h[u]; ~i; i = ne[i]) { //枚举的是每边相邻边 int j = e[i]; //此边,一端是t,另一端是j //此边边条w[i] f[j] += (f[u] + w[i] * g[u]) / out[u]; g[j] += g[u] / out[u]; // p[j]也需要概率累加 //拓扑序的标准套路 in[j]--; if (!in[j]) q.push(j); } } } int main() { //初始化邻接表 memset(h, -1, sizeof h); cin >> n >> m; while (m--) { int a, b, c; cin >> a >> b >> c; add(a, b, c); //维护出度,入度 out[a]++, in[b]++; } //拓扑序 topsort(); //正向递推,输出结果,保留两位小数 printf("%.2lf", f[n]); return 0; }