洛谷P2868 [USACO07DEC]观光奶牛Sightseeing Cows(01分数规划)
程序员文章站
2022-04-28 11:07:55
题意 "题目链接" Sol 复习一下01分数规划 设$a_i$为点权,$b_i$为边权,我们要最大化$\sum \frac{a_i}{b_i}$。可以二分一个答案$k$,我们需要检查$\sum \frac{a_i}{b_i} \geqslant k$是否合法,移向之后变为$\sum_{a_i} k\ ......
题意
sol
复习一下01分数规划
设\(a_i\)为点权,\(b_i\)为边权,我们要最大化\(\sum \frac{a_i}{b_i}\)。可以二分一个答案\(k\),我们需要检查\(\sum \frac{a_i}{b_i} \geqslant k\)是否合法,移向之后变为\(\sum_{a_i} - k\sum_{b_i} \geqslant 0\)。把\(k * b_i\)加在出发点的点权上检查一下有没有负环就行了
#include<bits/stdc++.h> #define pair pair<int, double> #define mp(x, y) make_pair(x, y) #define fi first #define se second //#define int long long #define ll long long #define fin(x) {freopen(#x".in","r",stdin);} #define fout(x) {freopen(#x".out","w",stdout);} using namespace std; const int maxn = 4001, mod = 998244353, inf = 2e9 + 10; const double eps = 1e-9; template <typename a, typename b> inline bool chmin(a &a, b b){if(a > b) {a = b; return 1;} return 0;} template <typename a, typename b> inline bool chmax(a &a, b b){if(a < b) {a = b; return 1;} return 0;} template <typename a, typename b> inline ll add(a x, b y) {if(x + y < 0) return x + y + mod; return x + y >= mod ? x + y - mod : x + y;} template <typename a, typename b> inline void add2(a &x, b y) {if(x + y < 0) x = x + y + mod; else x = (x + y >= mod ? x + y - mod : x + y);} template <typename a, typename b> inline ll mul(a x, b y) {return 1ll * x * y % mod;} template <typename a, typename b> inline void mul2(a &x, b y) {x = (1ll * x * y % mod + mod) % mod;} template <typename a> inline void debug(a a){cout << a << '\n';} template <typename a> inline ll sqr(a x){return 1ll * x * x;} inline int read() { char c = getchar(); int x = 0, f = 1; while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();} while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f; } int n, m; vector<pair> v[maxn]; double a[maxn], dis[maxn]; int vis[maxn], times[maxn]; bool spfa(int s, double k) { queue<int> q; q.push(s); for(int i = 1; i <= n; i++) vis[i] = 0, times[i] = 0, dis[i] = 0; times[s]++; while(!q.empty()) { int p = q.front(); q.pop(); vis[p] = 0; for(auto &sta : v[p]) { int to = sta.fi; double w = sta.se; if(chmax(dis[to], dis[p] + a[p] - k * w)) { if(!vis[to]) q.push(to), vis[to] = 1, times[to]++; if(times[to] > n) return 1; } } } return 0; } bool check(double val) { for(int i = 1; i <= n; i++) if(spfa(i, val)) return 1; return 0; } signed main() { n = read(); m = read(); for(int i = 1; i <= n; i++) a[i] = read(); for(int i = 1; i <= m; i++) { int x = read(), y = read(), z = read(); v[x].push_back({y, z}); } double l = -1e9, r = 1e9; while(r - l > eps) { double mid = (l + r) / 2; if(check(mid)) l = mid; else r = mid; } printf("%.2lf", l); return 0; }
上一篇: K2制作流程