Advertisement
Guest User

Untitled

a guest
Mar 29th, 2015
234
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.52 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <vector>
  5. #include <cstring>
  6. #include <string>
  7. #include <algorithm>
  8. #include <set>
  9. #include <map>
  10. #include <cmath>
  11. using namespace std;
  12.  
  13. #ifdef LOCAL
  14.     #define eprintf(...) fprintf(stderr, __VA_ARGS__)
  15. #else
  16.     #define eprintf(...) 42
  17. #endif
  18.  
  19. typedef long long ll;
  20.  
  21. const int IT = 200;
  22. const int INF_I = (int)1e9 + 10;
  23. const double INF = 1e10;
  24. const double eps1 = 1e-5;
  25. const int N = 300;
  26. const int V = 2 * N;
  27. const int E = N * N * 2;
  28. double x[N];
  29. double minValue[N][N], maxValue[N][N];
  30. int amount[N];
  31.  
  32. double height[N];
  33.  
  34. bool Eq(double a, double b, double e)
  35. {
  36.     return fabs(a - b) < e;
  37. }
  38.  
  39. bool Ls(double a, double b, double e)
  40. {
  41.     return a < b && !Eq(a, b, e);
  42. }
  43.  
  44. bool LsEq(double a, double b, double e)
  45. {
  46.     return a < b || Eq(a, b, e);
  47. }
  48.  
  49. bool Gr(double a, double b, double e)
  50. {
  51.     return a > b && !Eq(a, b, e);
  52. }
  53.  
  54. bool GrEq(double a, double b, double e)
  55. {
  56.     return a > b || Eq(a, b, e);
  57. }
  58.  
  59. ll scanDouble()
  60. {
  61.     char value[10];
  62.     ll result;
  63.     scanf("%s", value);
  64.     int len = strlen(value);
  65.     int pos = find(value, value + len, '.') - value;
  66.     if (pos >= len - 1)
  67.     {
  68.         sscanf(value, "%lld", &result);
  69.         result *= 1000;
  70.     }
  71.     else
  72.     {
  73.         ll a, b;
  74.         sscanf(value, "%lld.%lld", &a, &b);
  75.         result = a * 1000 + b;
  76.     }
  77.     return result;
  78. }
  79.  
  80. int mv = 0;
  81. int source = mv++;
  82. int sink = mv++;
  83. int sectionId[N];
  84. int colorId[N];
  85.  
  86. struct Edge
  87. {
  88.     int a, b;
  89.     double flow, cap;
  90.     Edge () {}
  91.     Edge (int _a, int _b, double _flow, double _cap) : a(_a), b(_b), flow(_flow), cap(_cap) {}
  92. };
  93.  
  94. Edge listEdges[E];
  95. vector <int> g[V];
  96. int dist[V];
  97. int ptr[V];
  98. int q[V];
  99. int indE = 0;
  100.  
  101. void markObjects(int n, int m)
  102. {
  103.     for (int i = 0; i < n; i++)
  104.         sectionId[i] = mv++;
  105.     for (int i = 0; i < m; i++)
  106.         colorId[i] = mv++;
  107. }
  108.  
  109. double maxH;
  110.  
  111. bool bfs(int v, int en)
  112. {
  113.     int topQ = 0;
  114.     fill(dist, dist + mv, INF_I);
  115.     q[topQ++] = v;
  116.     dist[v] = 0;
  117.     for (int i = 0; i < topQ; i++)
  118.     {
  119.         int curV = q[i];
  120.         for (int ie : g[curV])
  121.         {
  122.             Edge e = listEdges[ie];
  123.             if (!Eq(e.cap - e.flow, 0, eps1) && dist[e.b] > dist[e.a] + 1)
  124.             {
  125.                 dist[e.b] = dist[e.a] + 1;
  126.                 q[topQ++] = e.b;
  127.             }
  128.         }
  129.     }
  130.     return dist[en] != INF_I;
  131. }
  132.  
  133. double dfs(int v, int en, double flow)
  134. {
  135.     eprintf("v = %d, en = %d, flow = %lf\n", v, en, flow);
  136.     if (v == en)
  137.         return flow;
  138.     for (int &i = ptr[v]; i < (int)g[v].size(); i++)
  139.     {
  140.         int ie = g[v][i];
  141.         Edge e = listEdges[ie];
  142.         if (Gr(e.cap, e.flow, eps1) && dist[e.b] == dist[e.a] + 1)
  143.         {
  144.             double tmp = min(flow, e.cap - e.flow);
  145.             tmp = dfs(e.b, en, tmp);
  146.             if (!Eq(tmp, 0, eps1))
  147.             {
  148.                 listEdges[ie].flow += tmp;
  149.                 listEdges[ie ^ 1].flow -= tmp;
  150.                 return tmp;
  151.             }
  152.         }
  153.     }
  154.     return 0;
  155. }
  156.  
  157. double maxFlow()
  158. {
  159.     double flow = 0;
  160.     while (bfs(source, sink))
  161.     {
  162.         eprintf("dist[sink] = %d\n", dist[sink]);
  163.         fill(ptr, ptr + mv, 0);
  164.         double curFlow;
  165.         while (!Eq(curFlow = dfs(source, sink, INF), 0, eps1))
  166.             flow += curFlow;
  167.     }
  168.     return flow;
  169. }
  170.  
  171. void addEdge(int a, int b, double cap)
  172. {
  173.     g[a].push_back(indE);
  174.     listEdges[indE++] = Edge(a, b, 0, cap);
  175.  
  176.     g[b].push_back(indE);
  177.     listEdges[indE++] = Edge(b, a, 0, 0);
  178. }
  179.  
  180. void clear()
  181. {
  182.     indE = 0;
  183.     for (int i = 0; i < mv; i++)
  184.         g[i].clear();
  185. }
  186.  
  187. bool check(int n, int m, double maxDelta)
  188. {
  189.     eprintf("n = %d, m = %d, maxDelta = %lf\n", n, m, maxDelta);
  190.     clear();
  191.     double minH = maxH - maxDelta;
  192.     double neededFlow = 0;
  193.     for (int i = 0; i < n; i++)
  194.     {
  195.         if (GrEq(height[i], minH, eps1))
  196.             continue;
  197.         neededFlow += minH - height[i];
  198.         addEdge(source, sectionId[i], (x[i + 1] - x[i]) * (minH - height[i]));
  199.         for (int s = 0; s < m; s++)
  200.             addEdge(sectionId[i], colorId[i], maxValue[i][s] - minValue[i][s]);
  201.     }
  202.     for (int i = 0; i < m; i++)
  203.         addEdge(colorId[i], sink, amount[i]);
  204.  
  205.     double flow = maxFlow();
  206.     return GrEq(flow, neededFlow, eps1);
  207. }
  208.  
  209. int main()
  210. {
  211.     int n, m, w, h;
  212.     scanf("%d%d%d%d", &n, &m, &w, &h);
  213.     for (int i = 0; i < m; i++)
  214.         scanf("%d", &amount[i]);
  215.  
  216.     x[0] = 0;
  217.     for (int i = 1; i < n; i++)
  218.         scanf("%lf", &x[i]);
  219.     x[n] = w;
  220.  
  221.     for (int i = 0; i < n; i++)
  222.     {
  223.         for (int s = 0; s < m; s++)
  224.         {
  225.             scanf("%lf %lf", &minValue[i][s], &maxValue[i][s]);
  226.             height[i] += minValue[i][s] / (x[i + 1] - x[i]);
  227.             amount[s] -= minValue[i][s];
  228.         }
  229.     }
  230.  
  231.     maxH = *max_element(height, height + n);
  232.  
  233.     markObjects(n, m);
  234.     double l = 0, r = INF;
  235.     for (int i = 0; i < IT; i++)
  236.     {
  237.         double mid = (l + r) / 2;
  238.         if (check(n, m, mid))
  239.             r = mid;
  240.         else
  241.             l = mid;
  242.     }
  243.     printf("%.10lf", r);
  244.     return 0;
  245. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement