matistjati

Untitled

Jun 23rd, 2026
10
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.12 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 fl = INF;
  57. for (edge* x = par[t]; x; x = par[x->from])
  58. fl = min(fl, x->cap - x->flow);
  59.  
  60. totflow += fl;
  61. for (edge* x = par[t]; x; x = par[x->from]) {
  62. x->flow += fl;
  63. ed[x->to][x->rev].flow -= fl;
  64. }
  65. }
  66. rep(i,0,N) for(edge& e : ed[i]) totcost += e.cost * e.flow;
  67. return {totflow, totcost/2};
  68. }
  69.  
  70. // If some costs can be negative, call this before maxflow:
  71. void setpi(int s) { // (otherwise, leave this out)
  72. fill(all(pi), INF); pi[s] = 0;
  73. int it = N, ch = 1; ll v;
  74. while (ch-- && it--)
  75. rep(i,0,N) if (pi[i] != INF)
  76. for (edge& e : ed[i]) if (e.cap)
  77. if ((v = pi[i] + e.cost) < pi[e.to])
  78. pi[e.to] = v, ch = 1;
  79. assert(it >= 0); // negative cost cycle
  80. }
  81. };
  82.  
  83. int main() {
  84. cin.tie(0)->sync_with_stdio(0);
  85.  
  86. ll t;
  87. cin >> t;
  88.  
  89. while (t--)
  90. {
  91. ll m, n;
  92. cin >> m >> n;
  93. vector<string> grid(n);
  94. for (auto& s : grid) cin >> s;
  95.  
  96. MCMF mc(n * m * 3);
  97. auto getout = [&](ll x) {return x + n * m; };
  98. auto getller = [&](ll x) {return x + (n * m) * 2; };
  99.  
  100. rep(i, 0, n)
  101. {
  102. rep(j, 0, m)
  103. {
  104. ll ind = i * m + j;
  105.  
  106. if (i + 1 < n) mc.addEdge(getout(ind), ind + m, 2, 0);
  107. if (j + 1 < m) mc.addEdge(getout(ind), ind + 1, 2, 0);
  108.  
  109. if (grid[i][j] == '*')
  110. {
  111. mc.addEdge(ind, getout(ind), 1, 0);
  112. mc.addEdge(ind, getout(ind), 1, 1);
  113. }
  114. else if (grid[i][j] == '.')
  115. {
  116. mc.addEdge(ind, getout(ind), 2, 1);
  117. }
  118. }
  119. }
  120.  
  121. pair<ll,ll> res = mc.maxflow(0, getout(n * m - 1));
  122. cout << ((n + m - 1) * 2 - res.second) << "\n";
  123. }
  124.  
  125. return 0;
  126. }
  127.  
Advertisement
Add Comment
Please, Sign In to add comment