洛谷P4316 绿豆蛙的归宿
一眼看去,这不是高斯消元吗?
然后发现数据范围是100000...
然后发现是DAG...直接拓扑序递推即可。
边(x, y,z)的贡献是P(x) * z / out[x]
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <queue> 3 const int N = 100010; 4 5 struct Edge { 6 int v, nex, len; 7 }edge[N << 2]; int top; 8 9 int in[N], topo[N], e[N], n, out[N]; 10 double p[N]; 11 12 inline void add(int x, int y, int z) { 13 top++; 14 edge[top].v = y; 15 edge[top].len = z; 16 edge[top].nex = e[x]; 17 e[x] = top; 18 return; 19 } 20 21 inline void topo_sort() { 22 std::queue<int> Q; 23 for(int i = 1; i <= n; i++) { 24 if(!in[i]) { 25 Q.push(i); 26 } 27 } 28 int t = 0; 29 while(!Q.empty()) { 30 int x = Q.front(); 31 Q.pop(); 32 topo[++t] = x; 33 for(int i = e[x]; i; i = edge[i].nex) { 34 int y = edge[i].v; 35 in[y]--; 36 if(!in[y]) { 37 Q.push(y); 38 } 39 } 40 } 41 return; 42 } 43 44 int main() { 45 int m; 46 scanf("%d%d", &n, &m); 47 for(int i = 1, x, y, z; i <= m; i++) { 48 scanf("%d%d%d", &x, &y, &z); 49 add(x, y, z); 50 in[y]++; 51 out[x]++; 52 } 53 topo_sort(); 54 p[1] = 1.0; 55 double ans = 0.0; 56 for(int a = 1; a <= n; a++) { 57 int x = topo[a]; 58 for(int i = e[x]; i; i = edge[i].nex) { 59 int y = edge[i].v; 60 p[y] += p[x] / out[x]; 61 ans += p[x] * edge[i].len / out[x]; 62 } 63 } 64 printf("%.2lf", ans); 65 return 0; 66 }