matistjati

Untitled

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