链接:https://www.luogu.com.cn/problem/P4316
打个板子给自己看~
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define bug(x) cout << #x << " == " << x << endl;
#define INF 0x3f3f3f3f3f3f3f3f
#define inf 0x3f3f3f
const ll int MAX_N = 1e5 + 10;
struct node
{
int from, to, w;
} p[MAX_N];
int n, m;
int cnt;
int head[MAX_N];
int in[MAX_N] = {0};
int degree[MAX_N] = {0}; ///每一个点入度,反向建边的话,就是他的出度啦嘛
double dp[MAX_N] = {0};
inline void add_edge(int x, int y, int w)
{
cnt++;
p[cnt].from = head[x];
head[x] = cnt;
p[cnt].to = y;
p[cnt].w = w;
}
inline void tupusort()
{
queue<int> q;
q.push(n); ///n是起点惹
while (!q.empty())
{
int u = q.front();
q.pop();
for (int i = head[u]; i; i = p[i].from) ///找之前从x出发的边
{
int v = p[i].to; ///这条边到达的下一个点
dp[v] += (dp[u] + (double)p[i].w) / degree[v];
in[v]--; ///用过了一条边
if (in[v] == 0)
{
q.push(v); ///边都用过了 可以用来当起点啦
}
}
}
}
int main()
{
scanf("%d %d", &n, &m);
for (int i = 1; i <= m; i++)
{
int x, y, w;
scanf("%d %d %d", &x, &y, &w);
add_edge(y, x, w); 反向建边 这样子就可以反向拓扑了
in[x]++;
degree[x]++;
}
tupusort();
printf("%.2lf\n", dp[1]);
system("pause");
}