第一眼,卧槽这能做。。。

然后发现输出浮点数,不是要二分答案嘛。。。

于是就是二分答案,重构图然后判负圈。

判负圈的方法嘛,spfa即可。(大家这道题写的都是递归版的,于是蒟蒻也只敢写递归版的了T T)

结果跑到Rank1.上去了Oh耶!^_^

 

 1 /**************************************************************
 2     Problem: 1690
 3     User: rausen
 4     Language: C++
 5     Result: Accepted
 6     Time:20 ms
 7     Memory:920 kb
 8 ****************************************************************/
 9  
10 #include <cstdio>
11 #include <cstring>
12 #include <algorithm>
13  
14 using namespace std;
15 const int N = 1005;
16 const int M = 5005;
17 struct edges{
18     int next, to, V;
19     double v;
20 }e[M];
21 int n, m, tot, X, Y, Z;
22 int f[N], first[N];
23 bool flag, v[N];
24 double dis[N];
25  
26 inline int read(){
27     int x = 0, sgn = 1;
28     char ch = getchar();
29     while (ch < '0' || ch > '9'){
30         if (ch == '-') sgn = -1;
31         ch = getchar();
32     }
33     while (ch >= '0' && ch <= '9'){
34         x = x * 10 + ch - '0';
35         ch = getchar();
36     }
37     return sgn * x;
38 }
39  
40 void add_edge(int x, int y, int z){
41     e[++tot].next = first[x], first[x] = tot;
42     e[tot].to = y, e[tot].V = z;
43 }
44  
45 void build(double x){
46     for (int i = 1; i <= tot; ++i)
47         e[i].v = e[i].V * x - f[e[i].to];
48 }
49  
50 void spfa(int p){
51     v[p] = 1;
52     int x, y;
53     for (x = first[p]; x; x = e[x].next){
54         y = e[x].to;
55         if (e[x].v + dis[p] < dis[y]){
56             if (v[y]){
57                 flag = 1;
58                 return;
59             }
60             dis[y] = e[x].v + dis[p];
61             spfa(y);
62         }
63     }
64     v[p] = 0;
65 }
66  
67 inline bool check(){
68     memset(dis, 0, sizeof(dis));
69     memset(v, 0, sizeof(v));
70     flag = 0;
71     for (int i = 1; i <= n; ++i){
72         spfa(i);
73         if (flag) return 1;
74     }
75     return 0;
76 }
77  
78 int main(){
79     n = read(), m = read();
80     for (int i = 1; i <= n; ++i)
81         f[i] = read();
82     for (int i = 1; i <= m; ++i){
83         X = read(), Y = read(), Z = read();
84         add_edge(X, Y, Z);
85     }
86     double l = 0, r = 10000, mid;
87     while (r - l > 0.001){
88         mid = (l + r) / 2;
89         build(mid);
90         if (check()) l = mid;
91             else r = mid;
92     }
93     printf("%.2lf\n", l);
94     return 0;
95 }
View Code

 

posted on 2014-10-22 14:08  Xs酱~  阅读(229)  评论(0编辑  收藏  举报