Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cstdio>
- #include <cstdlib>
- #include <vector>
- #include <cstring>
- #include <string>
- #include <algorithm>
- #include <set>
- #include <map>
- #include <cmath>
- using namespace std;
- #ifdef LOCAL
- #define eprintf(...) fprintf(stderr, __VA_ARGS__)
- #else
- #define eprintf(...) 42
- #endif
- typedef long long ll;
- const int IT = 200;
- const int INF_I = (int)1e9 + 10;
- const double INF = 1e10;
- const double eps1 = 1e-5;
- const int N = 300;
- const int V = 2 * N;
- const int E = N * N * 2;
- double x[N];
- double minValue[N][N], maxValue[N][N];
- int amount[N];
- double height[N];
- bool Eq(double a, double b, double e)
- {
- return fabs(a - b) < e;
- }
- bool Ls(double a, double b, double e)
- {
- return a < b && !Eq(a, b, e);
- }
- bool LsEq(double a, double b, double e)
- {
- return a < b || Eq(a, b, e);
- }
- bool Gr(double a, double b, double e)
- {
- return a > b && !Eq(a, b, e);
- }
- bool GrEq(double a, double b, double e)
- {
- return a > b || Eq(a, b, e);
- }
- ll scanDouble()
- {
- char value[10];
- ll result;
- scanf("%s", value);
- int len = strlen(value);
- int pos = find(value, value + len, '.') - value;
- if (pos >= len - 1)
- {
- sscanf(value, "%lld", &result);
- result *= 1000;
- }
- else
- {
- ll a, b;
- sscanf(value, "%lld.%lld", &a, &b);
- result = a * 1000 + b;
- }
- return result;
- }
- int mv = 0;
- int source = mv++;
- int sink = mv++;
- int sectionId[N];
- int colorId[N];
- struct Edge
- {
- int a, b;
- double flow, cap;
- Edge () {}
- Edge (int _a, int _b, double _flow, double _cap) : a(_a), b(_b), flow(_flow), cap(_cap) {}
- };
- Edge listEdges[E];
- vector <int> g[V];
- int dist[V];
- int ptr[V];
- int q[V];
- int indE = 0;
- void markObjects(int n, int m)
- {
- for (int i = 0; i < n; i++)
- sectionId[i] = mv++;
- for (int i = 0; i < m; i++)
- colorId[i] = mv++;
- }
- double maxH;
- bool bfs(int v, int en)
- {
- int topQ = 0;
- fill(dist, dist + mv, INF_I);
- q[topQ++] = v;
- dist[v] = 0;
- for (int i = 0; i < topQ; i++)
- {
- int curV = q[i];
- for (int ie : g[curV])
- {
- Edge e = listEdges[ie];
- if (!Eq(e.cap - e.flow, 0, eps1) && dist[e.b] > dist[e.a] + 1)
- {
- dist[e.b] = dist[e.a] + 1;
- q[topQ++] = e.b;
- }
- }
- }
- return dist[en] != INF_I;
- }
- double dfs(int v, int en, double flow)
- {
- eprintf("v = %d, en = %d, flow = %lf\n", v, en, flow);
- if (v == en)
- return flow;
- for (int &i = ptr[v]; i < (int)g[v].size(); i++)
- {
- int ie = g[v][i];
- Edge e = listEdges[ie];
- if (Gr(e.cap, e.flow, eps1) && dist[e.b] == dist[e.a] + 1)
- {
- double tmp = min(flow, e.cap - e.flow);
- tmp = dfs(e.b, en, tmp);
- if (!Eq(tmp, 0, eps1))
- {
- listEdges[ie].flow += tmp;
- listEdges[ie ^ 1].flow -= tmp;
- return tmp;
- }
- }
- }
- return 0;
- }
- double maxFlow()
- {
- double flow = 0;
- while (bfs(source, sink))
- {
- eprintf("dist[sink] = %d\n", dist[sink]);
- fill(ptr, ptr + mv, 0);
- double curFlow;
- while (!Eq(curFlow = dfs(source, sink, INF), 0, eps1))
- flow += curFlow;
- }
- return flow;
- }
- void addEdge(int a, int b, double cap)
- {
- g[a].push_back(indE);
- listEdges[indE++] = Edge(a, b, 0, cap);
- g[b].push_back(indE);
- listEdges[indE++] = Edge(b, a, 0, 0);
- }
- void clear()
- {
- indE = 0;
- for (int i = 0; i < mv; i++)
- g[i].clear();
- }
- bool check(int n, int m, double maxDelta)
- {
- eprintf("n = %d, m = %d, maxDelta = %lf\n", n, m, maxDelta);
- clear();
- double minH = maxH - maxDelta;
- double neededFlow = 0;
- for (int i = 0; i < n; i++)
- {
- if (GrEq(height[i], minH, eps1))
- continue;
- neededFlow += minH - height[i];
- addEdge(source, sectionId[i], (x[i + 1] - x[i]) * (minH - height[i]));
- for (int s = 0; s < m; s++)
- addEdge(sectionId[i], colorId[i], maxValue[i][s] - minValue[i][s]);
- }
- for (int i = 0; i < m; i++)
- addEdge(colorId[i], sink, amount[i]);
- double flow = maxFlow();
- return GrEq(flow, neededFlow, eps1);
- }
- int main()
- {
- int n, m, w, h;
- scanf("%d%d%d%d", &n, &m, &w, &h);
- for (int i = 0; i < m; i++)
- scanf("%d", &amount[i]);
- x[0] = 0;
- for (int i = 1; i < n; i++)
- scanf("%lf", &x[i]);
- x[n] = w;
- for (int i = 0; i < n; i++)
- {
- for (int s = 0; s < m; s++)
- {
- scanf("%lf %lf", &minValue[i][s], &maxValue[i][s]);
- height[i] += minValue[i][s] / (x[i + 1] - x[i]);
- amount[s] -= minValue[i][s];
- }
- }
- maxH = *max_element(height, height + n);
- markObjects(n, m);
- double l = 0, r = INF;
- for (int i = 0; i < IT; i++)
- {
- double mid = (l + r) / 2;
- if (check(n, m, mid))
- r = mid;
- else
- l = mid;
- }
- printf("%.10lf", r);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement