Binary answer + Log retrieval + differential constraint + judgment Ring
In the question, the condition that a can \ (k \) double kill B is \ (s [a] \ geq k \ times s [B] \)
The first flag causes no women's clothes to be satisfied: \ (s [a] \ geq k \ times s [B] \). It means that a successfully kills B by \ (k \) times, and thus a does not need women's clothing.
The second flag causes no women's clothes to be satisfied: \ (s [B] <k \ times s [a] \) \ (s [a]> \ frac {s [B]} {k }\). It means that B cannot successfully \ (k \) double kill a, resulting in a no-women's wear.
With the influence of normal number \ (T \), the first flag is changed to \ (s [a] \ geq (k-T) \ times s [B] \). the second flag is changed to \ (s [a]> \ frac {s [B]} {k + t }\)
Obviously, the difficulty of inequality is related to \ (T. The larger the \ (T \), the less likely women's clothes to appear.
So we use a similar idea: make everyone the smallest \ (T \)Equal to or greaterThe largest \ (T \) of a person's women's clothes exists \)! Because the answer allows errors, it can be approximate.
Next is the most critical step:Retrieve log!
After obtaining the log, the first flag is changed to \ (\ log {s [a]} \ geq \ log {k} + \ log {s [B]} \). the second flag changes to \ (\ log {s [a]}> \ log {s [B]}-\ log {(K + T )}\).
Greater than and greater than or equal to can be equivalent here, as long as you add an EPS at the end, and your EPS must be much smaller than \ (10 ^ {-4, therefore, you can ignore it directly.
So we get a method similar to \ (Dist [v]> = DIST [u] + weight \), we can think of the difference constraint, you can create a graph to run the longest path to solve this problem!
The problem arises. How to Create a graph?
For flag1, we start from \ (B \) to \ (A \) connected \ (\ log k \) edge.
For flag2, we also forward \ (B \) to \ (A \) connected \ (-\ log k \) edge.
For known edge join tables, we use a virtual starting point to link the \ (\ log c \) edge from the starting point, in turn, you can connect the \ (-\ log c \) edge.
Finally, in order to concatenate the entire graph, we start from the virtual start point to the edge with a weight of 0 for all vertices.
We can find that the obtained Dist comes with log.
How can I determine whether the answer is valid? You only need to find a solution to this equation.
How can this problem be solved? There is no right ring!
The Judgment Method of the positive ring is the same as that of the negative ring.
Code:
#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<queue>const int maxn = 1005;const double INF = 1e18;const double eps = 1e-10;struct Edges{ int next, to, id; double weight;} e[1000005];int head[maxn], tot;double dist[maxn];bool vis[maxn];int cnt[maxn];double left = eps, right = INF, ans = -1;int n, s, t;int read(){ int ans = 0, s = 1; char ch = getchar(); while(ch > ‘9‘ || ch < ‘0‘){ if(ch == ‘-‘) s = -1; ch = getchar(); } while(ch >= ‘0‘ && ch <= ‘9‘) ans = ans * 10 + ch - ‘0‘, ch = getchar(); return s * ans;}void link(int u, int v, double w, int i){ e[++tot] = (Edges){head[u], v, i, w}; head[u] = tot;}bool check(double T){ std::queue<int> q; memset(vis, false, sizeof vis); for(int i = 0; i <= n + 3; i++) dist[i] = -INF; memset(cnt, 0, sizeof cnt); q.push(n + 1); dist[n + 1] = 0; vis[n + 1] = true; cnt[n + 1]++; while(!q.empty()) { int u = q.front(); q.pop(); vis[u] = false; for(int i = head[u]; i; i = e[i].next) { int v = e[i].to; double weight; if(e[i].id == 1) weight = log2(e[i].weight - T); else if(e[i].id == 2) weight = -log2(e[i].weight + T); else weight = e[i].weight; if(dist[v] < dist[u] + weight) { dist[v] = dist[u] + weight; if(!vis[v]) { q.push(v); vis[v] = true; if(++cnt[v] == n + 1) return false; } } } } return true;}int main(){ n = read(), s = read(), t = read(); for(int i = 1; i <= s; i++) { int o = read(), a = read(), b = read(), k = read(); if(o == 1) { link(b, a, k, 1); right = std::min(right, (double)k); } else if(o == 2) { link(b, a, k, 2); } } for(int i = 1; i <= t; i++) { int c = read(), x = read(); link(0, c, log2(x), 4); link(c, 0, -log2(x), 4); } for(int i = 0; i <= n; i++) link(n + 1, i, 0, 0); if(check(0)) { printf("-1\n"); return 0; } while(right - left > eps) { double mid = (left + right) / 2; if(check(mid)) right = mid; else left = mid; } printf("%.8lf\n", left); return 0;}
P4926 [1007] times to kill Surveyors