[题目链接]
http://poj.org/problem?id=3621
[算法]
01分数规划(最优比率环)
[代码]
#include <algorithm> #include <bitset> #include <cctype> #include <cerrno> #include <clocale> #include <cmath> #include <complex> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <deque> #include <exception> #include <fstream> #include <functional> #include <limits> #include <list> #include <map> #include <iomanip> #include <ios> #include <iosfwd> #include <iostream> #include <istream> #include <ostream> #include <queue> #include <set> #include <sstream> #include <stdexcept> #include <streambuf> #include <string> #include <utility> #include <vector> #include <cwchar> #include <cwctype> #include <stack> #include <limits.h> using namespace std; #define MAXL 1010 #define MAXP 5010 const double eps = 1e-4; const int T = 1e5; const int INF = 2e9; struct edge { int to,w,nxt; } e[MAXP]; int i,L,P,a,b,w,tot; int f[MAXL],head[MAXL]; double l,r,mid,ans; inline void addedge(int u,int v,int w) { tot++; e[tot] = (edge){v,w,head[u]}; head[u] = tot; } inline bool spfa(double mid) { int i,cur,v; double w; static int cnt[MAXL]; static bool inq[MAXL]; static double dist[MAXL]; queue< int > q; memset(cnt,0,sizeof(cnt)); memset(inq,false,sizeof(inq)); while (!q.empty()) q.pop(); for (i = 1; i <= L; i++) { q.push(i); cnt[i] = 1; inq[i] = true; dist[i] = -INF; } while (!q.empty()) { cur = q.front(); q.pop(); inq[cur] = false; for (i = head[cur]; i; i = e[i].nxt) { v = e[i].to; w = 1.0 * f[cur] - 1.0 * mid * e[i].w; if (dist[cur] + w > dist[v]) { dist[v] = dist[cur] + w; if (!inq[v]) { inq[v] = true; cnt[v]++; if (cnt[v] > L) return true; q.push(v); } } } } return false; } int main() { scanf("%d%d",&L,&P); for (i = 1; i <= L; i++) scanf("%d",&f[i]); for (i = 1; i <= P; i++) { scanf("%d%d%d",&a,&b,&w); addedge(a,b,w); } l = 0; r = T; while (r - l > eps) { mid = (l + r) / 2.0; if (spfa(mid)) { ans = mid; l = mid; } else r = mid; } printf("%.2f ",ans); return 0; }