Advertisement
a53

tobruk

a53
Sep 13th, 2020
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.51 KB | None | 0 0
  1. #include <fstream>
  2. #include <algorithm>
  3. #include <vector>
  4. #include <queue>
  5. #include <utility>
  6. #include <limits>
  7. #include <cctype>
  8.  
  9. using namespace std;
  10.  
  11.  
  12. ifstream fin ("tobruk.in");
  13. ofstream fout ("tobruk.out");
  14.  
  15. struct base_t {
  16. int_fast64_t position, defense, oil;
  17. friend ifstream& operator >> (ifstream& flux, base_t& b) {
  18. flux >> b.position >> b.defense >> b.oil;
  19. return flux;
  20. }
  21. bool operator < (const base_t& b) const {
  22. return this->defense < b.defense;
  23. }
  24. };
  25.  
  26. struct squad_t {
  27. int_fast64_t position, strength, fuel, price;
  28. friend ifstream& operator >> (ifstream& flux, squad_t& s) {
  29. flux >> s.position >> s.strength >> s.fuel >> s.price;
  30. return flux;
  31. }
  32. };
  33.  
  34. class Dinic;
  35. class Flow_Edge {
  36. private:
  37. int from, to;
  38. int_fast64_t capacity, flow = 0LL;
  39. public:
  40. Flow_Edge (const int& from, const int& to, const int_fast64_t& capacity): from (from), to (to), capacity (capacity) {
  41. }
  42. friend Dinic;
  43. };
  44.  
  45. constexpr auto Inf = numeric_limits <int_fast64_t>::max () >> 1LL;
  46. using Ip = pair <int_fast64_t, int_fast64_t>;
  47. using Vi = vector <int>;
  48. using VVi = vector <Vi>;
  49. using Vi64 = vector <int_fast64_t>;
  50. using VVi64 = vector <Vi64>;
  51. using VIp = vector <Ip>;
  52. using VVIp = vector <VIp>;
  53. using Vf = vector <Flow_Edge>;
  54. using Vs = vector <squad_t>;
  55. using Vb = vector <base_t>;
  56. using Qi = queue <int>;
  57.  
  58. class Dinic {
  59. private:
  60. Vf Edges;
  61. VVi Adj;
  62. int n, s, t;
  63. Vi Level, Ptr;
  64. Qi Q;
  65. bool bfs () {
  66. while (!Q.empty ()) {
  67. int v = Q.front (); Q.pop ();
  68. for (const auto& id: Adj[v]) {
  69. if (Edges[id].capacity - Edges[id].flow < 1)
  70. continue;
  71. if (Level[Edges[id].to] != -1)
  72. continue;
  73. Level[Edges[id].to] = Level[v] + 1;
  74. Q.push (Edges[id].to);
  75. }
  76. }
  77. return Level[t] != -1;
  78. }
  79. int_fast64_t dfs (const int& v, const int_fast64_t& pushed) {
  80. if (!pushed)
  81. return 0LL;
  82. if (v == t)
  83. return pushed;
  84. for (int& cid = Ptr[v]; cid < (int)Adj[v].size (); ++ cid) {
  85. int id = Adj[v][cid], u = Edges[id].to;
  86. if (Level[v] + 1 != Level[u] || Edges[id].capacity - Edges[id].flow < 1)
  87. continue;
  88. int_fast64_t transport = dfs (u, min (pushed, Edges[id].capacity - Edges[id].flow));
  89. if (!transport)
  90. continue;
  91. Edges[id].flow += transport;
  92. Edges[id ^ 1].flow -= transport;
  93. return transport;
  94. }
  95. return 0LL;
  96. }
  97. public:
  98. Dinic (const int& n, const int& s, const int& t): n (n), s (s), t (t) {
  99. Adj.resize (n), Level.resize (n), Ptr.resize (n);
  100. }
  101. void add_edge (const int& u, const int& v, const int_fast64_t& cap) {
  102. if (u == v) return;
  103. Edges.emplace_back (u, v, cap);
  104. Adj[u].emplace_back (Edges.size () - 1);
  105. Edges.emplace_back (v, u, 0);
  106. Adj[v].emplace_back (Edges.size () - 1);
  107. }
  108. int_fast64_t max_flow () {
  109. int_fast64_t f = 0LL;
  110. while (true) {
  111. fill (Level.begin (), Level.end (), -1);
  112. Level[s] = 0;
  113. Q.push (s);
  114. if (!bfs ())
  115. break;
  116. fill (Ptr.begin (), Ptr.end (), 0);
  117. while (int_fast64_t pushed = dfs (s, Inf))
  118. f += pushed;
  119. }
  120. return f;
  121. }
  122. };
  123.  
  124.  
  125. int n, m, u, v, s, b, k;
  126. Vi64 Value;
  127. VVi64 Cost;
  128. Vs Squads;
  129. Vb Bases;
  130. VVIp Bases_at;
  131.  
  132.  
  133. int main () {
  134. fin >> n >> m;
  135. Cost.assign (n + 1, Vi64 (n + 1, Inf));
  136. for (int i = 1; i <= n; ++ i) Cost[i][i] = 0LL;
  137. for (int i = 1; i <= m; ++ i)
  138. fin >> u >> v, Cost[u][v] = Cost[v][u] = min (Cost[u][v], 1LL);
  139.  
  140. for (int k = 1; k <= n; ++ k)
  141. for (int i = 1; i <= n; ++ i)
  142. for (int j = 1; j <= n; ++ j)
  143. Cost[i][j] = min (Cost[i][j], Cost[i][k] + Cost[k][j]);
  144.  
  145. fin >> s >> b >> k;
  146. Value.resize (s + 1), Bases_at.resize (n + 1);
  147. Squads.resize (s + 1), Bases.resize (b + 1);
  148. for (int i = 1; i <= s; ++ i)
  149. fin >> Squads[i];
  150. for (int i = 1; i <= b; ++ i)
  151. fin >> Bases[i];
  152.  
  153. sort (Bases.begin (), Bases.end ());
  154. for (int i = 1; i <= b; ++ i) {
  155. int pos = Bases[i].position;
  156. if (Bases_at[pos].empty () || Bases_at[pos].back ().second < Bases[i].oil)
  157. Bases_at[pos].emplace_back (Bases[i].defense, Bases[i].oil);
  158. }
  159.  
  160. int source = 0, sink = s + 1;
  161. Dinic dinic (s + 2, source, sink);
  162. int_fast64_t ans = 0LL;
  163. for (int i = 1; i <= s; ++ i) {
  164. bool found = false;
  165. for (int p = 1; p <= n; ++ p) {
  166. if (Cost[Squads[i].position][p] > Squads[i].fuel)
  167. continue;
  168. auto it = upper_bound (Bases_at[p].begin (), Bases_at[p].end (), make_pair (Squads[i].strength, Inf));
  169. if (it != Bases_at[p].begin ())
  170. -- it, found = true, Value[i] = max (Value[i], it->second);
  171. }
  172. Value[i] -= Squads[i].price;
  173. if (!found)
  174. Value[i] = -Inf;
  175. if (Value[i] >= 0)
  176. ans += Value[i], dinic.add_edge (source, i, Value[i]);
  177. else
  178. dinic.add_edge (i, sink, -Value[i]);
  179. }
  180.  
  181. for (int i = 1; i <= k; ++ i)
  182. fin >> u >> v,
  183. dinic.add_edge (u, v, Inf);
  184.  
  185. fout << ans - dinic.max_flow ();
  186.  
  187. fin.close (), fout.close ();
  188. return 0;
  189. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement