洛谷P4316 绿豆蛙的归宿

一眼看去,这不是高斯消元吗?

然后发现数据范围是100000...

然后发现是DAG...直接拓扑序递推即可。

边(x, y,z)的贡献是P(x) * z / out[x]

 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 }
AC代码

 

posted @ 2018-08-31 11:33  garage  阅读(84)  评论(0编辑  收藏  举报