luogu P1768 天路

嘟嘟嘟

01分数规划之最优比率环。

主要是发一下基于dfs的spfa。跑的贼快,原来总用时2000多ms还TLE了两个点,改成dfs后总用时直降43ms!

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<cstdlib>
 7 #include<cctype>
 8 #include<stack>
 9 #include<queue>
10 #include<vector>
11 using namespace std;
12 #define enter puts("")
13 #define space putchar(' ')
14 #define Mem(a, x) memset(a, x, sizeof(a))
15 #define rg register
16 typedef long long ll;
17 typedef double db;
18 const int INF = 0x3f3f3f3f;
19 const db eps = 1e-4;
20 const int maxn = 7e3 + 5;
21 const int maxe = 4e4 + 5;
22 inline ll read()
23 {
24   ll ans = 0;
25   char ch = getchar(), las = ' ';
26   while(!isdigit(ch)) las = ch, ch = getchar();
27   while(isdigit(ch)) ans = (ans << 3) + (ans << 1) + ch - '0', ch = getchar();
28   if(las == '-') ans = -ans;
29   return ans;
30 }
31 inline void write(ll x)
32 {
33   if(x < 0) putchar('-'), x = -x;
34   if(x >= 10) write(x / 10);
35   putchar(x % 10 + '0');
36 }
37 
38 int n, m;
39 struct Edge
40 {
41   int nxt, to, v, p;
42 }e[maxe];
43 int head[maxn], ecnt = -1;
44 void addEdge(int x, int y, int v, int p)
45 {
46   e[++ecnt] = (Edge){head[x], y, v, p};
47   head[x] = ecnt;
48 }
49 
50 bool in[maxn];
51 db dis[maxn];
52 bool judge(db x, int now)
53 {
54   in[now] = 1;
55   for(int i = head[now]; i != -1; i = e[i].nxt)
56     {
57       if(dis[e[i].to] > x * (db)e[i].p - (db)e[i].v + dis[now])
58     {
59       if(in[e[i].to]) return 1;
60       dis[e[i].to] = x * (db)e[i].p - (db)e[i].v + dis[now];
61       in[e[i].to] = 1;
62       if(judge(x, e[i].to)) return 1;
63     }
64     }
65   in[now] = 0;
66   return 0;
67 }
68 
69 int main()
70 {
71   Mem(head, -1);
72   n = read(); m = read();
73   for(int i = 1; i <= m; ++i)
74     {
75       int x = read(), y = read(), v = read(), p = read();
76       addEdge(x, y, v, p);
77     }
78   for(int i = 1; i <= n; ++i) addEdge(0, i, 0, 0); //搞一个超级源点
79   db L = 0, R = 2000;
80   while(R - L > eps)
81     {
82       db mid = (L + R) / 2;
83       Mem(dis, 0x3f); Mem(in, 0); dis[0] = 0;
84       if(judge(mid, 0)) L = mid;
85       else R = mid - eps;
86     }
87   if(L < eps) write(-1), enter;
88   else printf("%.1lf
", L);
89   return 0;
90 }
View Code
原文地址:https://www.cnblogs.com/mrclr/p/9836488.html