fork download
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define ll long long
  5. #define el cout << '\n'
  6.  
  7. const int MAXN = 5;
  8. const int MAXM = 100000;
  9. const int MAXQ = 100000;
  10. const ll INF = (ll)4e18; // lớn hơn tổng chi phí khả dĩ
  11.  
  12. const int dx[] = {0, 1, 0, -1};
  13. const int dy[] = {1, 0, -1, 0};
  14.  
  15. struct Query {
  16. int x, y, u, v, id;
  17. Query(int x=0,int y=0,int u=0,int v=0,int id=0):x(x),y(y),u(u),v(v),id(id){}
  18. };
  19. struct Node {
  20. int x, y;
  21. ll dist;
  22. Node(int x=0,int y=0,ll dist=0):x(x),y(y),dist(dist){}
  23. bool operator>(const Node &other) const { return dist > other.dist; }
  24. };
  25.  
  26. int n, m, q;
  27. ll a[MAXN + 5][MAXM + 5];
  28. static ll dist_arr[MAXN + 5][MAXN + 5][MAXM + 5]; // dist[id][row][col]
  29. ll ans[MAXQ + 5];
  30. vector<Query> qrs;
  31.  
  32. inline void dijkstra(int id, int L, int R, int sx, int sy) {
  33. // set INF for the needed columns [L..R] for all rows
  34. for (int i = 1; i <= n; ++i) {
  35. // dist_arr[id][i] + L..R are contiguous in memory (last index varies fastest)
  36. std::fill(dist_arr[id][i] + L, dist_arr[id][i] + R + 1, INF);
  37. }
  38.  
  39. priority_queue<Node, vector<Node>, greater<Node>> pq;
  40. dist_arr[id][sx][sy] = a[sx][sy];
  41. pq.push(Node(sx, sy, dist_arr[id][sx][sy]));
  42.  
  43. while (!pq.empty()) {
  44. Node cur = pq.top(); pq.pop();
  45. int x = cur.x, y = cur.y;
  46. ll d = cur.dist;
  47. if (d != dist_arr[id][x][y]) continue;
  48.  
  49. for (int k = 0; k < 4; ++k) {
  50. int nx = x + dx[k], ny = y + dy[k];
  51. if (nx < 1 || nx > n || ny < L || ny > R) continue;
  52. ll nd = d + a[nx][ny];
  53. if (nd < dist_arr[id][nx][ny]) {
  54. dist_arr[id][nx][ny] = nd;
  55. pq.push(Node(nx, ny, nd));
  56. }
  57. }
  58. }
  59. }
  60.  
  61. void dnc(int L, int R, vector<Query> &vec) {
  62. if (vec.empty()) return;
  63. int mid = (L + R) >> 1; // **SỬA**: dùng mid đúng (không phải l + r >> 1)
  64.  
  65. // Chạy Dijkstra từ mỗi hàng (row) với nguồn là cột mid
  66. for (int row = 1; row <= n; ++row) {
  67. dijkstra(row, L, R, row, mid);
  68. }
  69.  
  70. // Cập nhật câu trả lời bằng cách thử mọi row làm "điểm nối" qua cột mid
  71. for (const Query &qr : vec) {
  72. for (int row = 1; row <= n; ++row) {
  73. // dist_arr[row][x][y] + dist_arr[row][u][v] - a[row][mid]
  74. ll cand = dist_arr[row][qr.x][qr.y];
  75. ll cand2 = dist_arr[row][qr.u][qr.v];
  76. if (cand >= INF || cand2 >= INF) continue;
  77. ll total = cand + cand2 - a[row][mid];
  78. if (total < ans[qr.id]) ans[qr.id] = total;
  79. }
  80. }
  81.  
  82. if (L == R) return;
  83.  
  84. int M = mid;
  85. vector<Query> left_qs; left_qs.reserve(vec.size());
  86. vector<Query> right_qs; right_qs.reserve(vec.size());
  87.  
  88. for (const Query &qr : vec) {
  89. if (qr.v <= M) left_qs.push_back(qr);
  90. else if (qr.y > M) right_qs.push_back(qr);
  91. else {
  92. // trường hợp đường đi giao nhau hai phía: vẫn đã được cập nhật ở trên (qua mid)
  93. // không cần push xuống con nào vì câu trả lời đã xét qua mid
  94. }
  95. }
  96.  
  97. dnc(L, M, left_qs);
  98. dnc(M+1, R, right_qs);
  99. }
  100.  
  101. int main() {
  102. ios::sync_with_stdio(false);
  103. cin.tie(nullptr);
  104.  
  105. // Hỗ trợ đọc từ file nếu có (giữ nguyên ý định ban đầu)
  106. if (fopen("SHORTEST.INP", "r")) {
  107. freopen("SHORTEST.INP", "r", stdin);
  108. freopen("SHORTEST.OUT", "w", stdout);
  109. }
  110.  
  111. cin >> n >> m;
  112. for (int i = 1; i <= n; ++i)
  113. for (int j = 1; j <= m; ++j)
  114. cin >> a[i][j];
  115.  
  116. cin >> q;
  117. qrs.reserve(q);
  118. for (int i = 1; i <= q; ++i) {
  119. int x,y,u,v; cin >> x >> y >> u >> v;
  120. if (y > v) { swap(x,u); swap(y,v); } // đảm bảo y <= v
  121. qrs.push_back(Query(x,y,u,v,i));
  122. ans[i] = INF;
  123. }
  124.  
  125. dnc(1, m, qrs);
  126.  
  127. for (int i = 1; i <= q; ++i) {
  128. cout << ans[i] << '\n';
  129. }
  130. return 0;
  131. }
  132.  
Success #stdin #stdout 0.01s 5320KB
stdin
Standard input is empty
stdout
Standard output is empty