做題記錄 Luogu P2868
阿新 • • 發佈:2021-06-26
Luogu P2868 [USACO07DEC]Sightseeing Cows G
分數規劃。
#include<bits/stdc++.h> using namespace std; #define N 100005 struct edge { int from, to, w, Next; }; edge e[N]; const double eps = 1e-6; int first[N], n, m, tot; double a[N], dis[N]; int vis[N], mark[N]; void add(int x, int y, int z) { e[++tot].Next = first[x]; first[x] = tot; e[tot].from = x; e[tot].to = y; e[tot].w = z; } int spfa(int x, double mid) { vis[x] = 1; mark[x] = 1; for(int i = first[x]; i; i = e[i].Next) { int v = e[i].to; double w = mid * e[i].w - a[v]; if(dis[x] + w < dis[v]) { dis[v] = dis[x] + w; if(mark[v]) { return 1; } if(spfa(v, mid)) { return 1; } } } mark[x] = 0; return 0; } int check(double x) { memset(vis, 0, sizeof(vis)); memset(mark, 0, sizeof(mark)); for(int i = 1; i <= n; i++) { dis[i] = 1e9; } for(int i = 1; i <= n; i++) { if(!vis[i]) { if(spfa(i, x)) { return 1; } } } return 0; } int main() { scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) { scanf("%lf", &a[i]); } int u, v, w; for(int i = 1; i <= m; i++) { scanf("%d%d%d", &u, &v, &w); add(u, v, w); } double l = 0, r = 1e5, mid; while(r - l > eps) { mid = (l + r) / 2; if(check(mid)) { l = mid; } else { r = mid; } } printf("%0.2lf", l); return 0; }