matistjati

Untitled

Jun 24th, 2026
9
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.63 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define rep(i, a, b) for(int i = a; i < (b); ++i)
  5. #define all(x) begin(x), end(x)
  6. #define sz(x) (int)(x).size()
  7. typedef long long ll;
  8. typedef pair<int, int> pii;
  9. typedef vector<int> vi;
  10.  
  11. #include <bits/extc++.h> /// include-line, keep-include
  12.  
  13. const ll INF = numeric_limits<ll>::max() / 4;
  14.  
  15. struct MCMF {
  16. struct edge {
  17. int from, to, rev;
  18. ll cap, cost, flow;
  19. };
  20. int N;
  21. vector<vector<edge>> ed;
  22. vi seen;
  23. vector<ll> dist, pi;
  24. vector<edge*> par;
  25.  
  26. MCMF(int N) : N(N), ed(N), seen(N), dist(N), pi(N), par(N) {}
  27.  
  28. void addEdge(int from, int to, ll cap, ll cost) {
  29. if (from == to) return;
  30. ed[from].push_back(edge{ from,to,sz(ed[to]),cap,cost,0 });
  31. ed[to].push_back(edge{ to,from,sz(ed[from])-1,0,-cost,0 });
  32. }
  33.  
  34. void path(int s) {
  35. fill(all(seen), 0);
  36. fill(all(dist), INF);
  37. dist[s] = 0; ll di;
  38.  
  39. __gnu_pbds::priority_queue<pair<ll, int>> q;
  40. vector<decltype(q)::point_iterator> its(N);
  41. q.push({ 0, s });
  42.  
  43. while (!q.empty()) {
  44. s = q.top().second; q.pop();
  45. seen[s] = 1; di = dist[s] + pi[s];
  46. for (edge& e : ed[s]) if (!seen[e.to]) {
  47. ll val = di - pi[e.to] + e.cost;
  48. if (e.cap - e.flow > 0 && val < dist[e.to]) {
  49. dist[e.to] = val;
  50. par[e.to] = &e;
  51. if (its[e.to] == q.end())
  52. its[e.to] = q.push({ -dist[e.to], e.to });
  53. else
  54. q.modify(its[e.to], { -dist[e.to], e.to });
  55. }
  56. }
  57. }
  58. rep(i,0,N) pi[i] = min(pi[i] + dist[i], INF);
  59. }
  60.  
  61. pair<ll, ll> maxflow(int s, int t) {
  62. ll totflow = 0, totcost = 0;
  63. while (path(s), seen[t]) {
  64. ll c = 0;
  65. for (edge* x = par[t]; x; x = par[x->from])
  66. c += x->cost;
  67.  
  68. if (c > 0) break;
  69.  
  70. ll fl = INF;
  71. for (edge* x = par[t]; x; x = par[x->from])
  72. fl = min(fl, x->cap - x->flow);
  73.  
  74. totflow += fl;
  75. for (edge* x = par[t]; x; x = par[x->from]) {
  76. x->flow += fl;
  77. ed[x->to][x->rev].flow -= fl;
  78. }
  79. }
  80. rep(i,0,N) for(edge& e : ed[i]) totcost += e.cost * e.flow;
  81. return {totflow, totcost/2};
  82. }
  83.  
  84. // If some costs can be negative, call this before maxflow:
  85. void setpi(int s) { // (otherwise, leave this out)
  86. fill(all(pi), INF); pi[s] = 0;
  87. int it = N, ch = 1; ll v;
  88. while (ch-- && it--)
  89. rep(i,0,N) if (pi[i] != INF)
  90. for (edge& e : ed[i]) if (e.cap)
  91. if ((v = pi[i] + e.cost) < pi[e.to])
  92. pi[e.to] = v, ch = 1;
  93. assert(it >= 0); // negative cost cycle
  94. }
  95. };
  96.  
  97. int main() {
  98. cin.tie(0)->sync_with_stdio(0);
  99.  
  100. const int inf = 1e9;
  101. int r, c, b, t;
  102. cin >> c >> r >> b >> t;
  103. vector<vector<vi>> whomst(r, vector<vi>(c));
  104.  
  105. vector<string> grid(r);
  106. rep(i, 0, r) cin >> grid[i];
  107. pii goal;
  108. rep(i, 0, r) rep(j, 0, c) if (grid[i][j] == 'K') goal = pii(i, j);
  109. vector<pii> targets;
  110. rep(i, 0, t) {
  111. int a, b;
  112. cin >> b >> a;
  113. a--; b--;
  114. targets.emplace_back(a, b);
  115. }
  116. t++;
  117. targets.push_back(goal);
  118. rep(i, 0, t) {
  119. whomst[targets[i].first][targets[i].second].push_back(i);
  120. }
  121.  
  122. using p3 = tuple<int, int, int>;
  123. vector<vi> dist(t, vi(t, inf));
  124. vector<pii> dirs = { {0,1},{0,-1},{1,0},{-1,0} };
  125. rep(i, 0, t) {
  126. queue<p3> q;
  127. q.emplace(0, targets[i].first, targets[i].second);
  128. vector<vi> vis(r, vi(c));
  129. while (q.size())
  130. {
  131. int d, a, b;
  132. tie(d, a, b) = q.front();
  133. q.pop();
  134. if (vis[a][b]) continue;
  135. vis[a][b] = 1;
  136. for (auto w : whomst[a][b]) dist[i][w] = d;
  137.  
  138. for (auto dir : dirs) {
  139. pii np = pii(a + dir.first, b + dir.second);
  140. if (np.first < 0 || np.second < 0 || np.first >= r || np.second >= c) continue;
  141. if (grid[np.first][np.second] == '#') continue;
  142. q.emplace(d + 1, np.first, np.second);
  143. }
  144. }
  145. }
  146. rep(i, 0, t) {
  147. if (dist[i][t - 1] == inf) {
  148. cout << "impossible";
  149. return 0;
  150. }
  151. }
  152. int nodecnt = (t - 1) * 2 + 3;
  153. MCMF flow(nodecnt);
  154.  
  155. flow.addEdge(nodecnt - 2, nodecnt - 3, b, 0);
  156. rep(i, 0, t - 1) {
  157. flow.addEdge(nodecnt - 3, i * 2, inf, dist[t - 1][i]);
  158. }
  159. rep(i, 0, t - 1) {
  160. flow.addEdge(i * 2, i * 2 + 1, 1, -inf);
  161. }
  162. rep(i, 0, t - 1) {
  163. flow.addEdge(i * 2 + 1, nodecnt - 1, inf, dist[i][t - 1]);
  164. }
  165. rep(i, 0, t - 1) {
  166. rep(j, i + 1, t - 1) {
  167. flow.addEdge(i * 2 + 1, j * 2, inf, dist[i][j]);
  168. }
  169. }
  170. flow.setpi(nodecnt - 2);
  171. auto [_, cost] = flow.maxflow(nodecnt - 2, nodecnt - 1);
  172. cout << cost + (ll)(t - 1) * inf;
  173.  
  174. return 0;
  175. }
  176.  
Add Comment
Please, Sign In to add comment