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 }