1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| #include <algorithm> #include <iostream> #include <cstring> #include <climits> #include <cstdio> #include <vector> #include <queue>
#define FILE_IN(__fname) freopen(__fname, "r", stdin) #define FILE_OUT(__fname) freopen(__fname, "w", stdout) #define rap(a,s,t,i) for (int a = s; a <= t; a += i) #define basketball(a,t,s,i) for (int a = t; a > s; a -= i) #define countdown(s) while (s --> 0) #define IMPROVE_IO() std::ios::sync_with_stdio(false)
using std::cin; using std::cout; using std::endl;
typedef long long int lli;
int getint() { int x; scanf("%d", &x); return x; } lli getll() { long long int x; scanf("%lld", &x); return x; }
const int MAXN = 3000 + 10; const int MAXM = 10000 + 10; const double eps = 1e-10;
struct Edge { int v; double w; Edge(int v = 0, double w = 0.0) : v(v), w(w) {} };
std::vector<Edge> head[MAXN];
int n, m; double dis[MAXN]; bool inQueue[MAXN], negLoop;
inline void addEdge(int u, int v, double w) { head[u].push_back(Edge(v, w)); } inline void Modify(double w) { for (int i = 1; i <= n; ++i) { for (int k = 0, siz = (int) head[i].size(); k < siz; ++k) { head[i][k].w += w; } } }
void SPFA_NegativeLoop(int st) { inQueue[st] = true; if (negLoop) return; for (int i = 0, siz = (int) head[st].size(); i < siz; ++i) { int next = head[st][i].v; if (dis[next] > dis[st] + head[st][i].w) { if (inQueue[next]) { return (void) (negLoop = true); } dis[next] = dis[st] + head[st][i].w; SPFA_NegativeLoop(next); } } inQueue[st] = false; }
bool Check(double mid) { memset(dis, 0, sizeof dis); memset(inQueue, false, sizeof inQueue); negLoop = false; Modify(-mid); for (int i = 1; i <= n; ++i) { SPFA_NegativeLoop(i); if (negLoop) break; } Modify(mid); return negLoop; }
int main() { n = getint(); m = getint(); double l = INT_MAX, r = 0; rap (i, 1, m, 1) { int u = getint(), v = getint(); double w = 0.0; scanf("%lf", &w); addEdge(u, v, w); l = std::min(w, l); r = std::max(w, r); } double ans = 0; while (l - r < eps) { double mid = (l + r) / 2; if (Check(mid)) { r = mid - eps; ans = r; } else l = mid + eps; } printf("%0.8lf", ans); return 0; }
|