Codeforces Round #619 (Div. 2) F. Super Jaber BFS最短路

布满荆棘的人生 2023-07-15 13:25 7阅读 0赞

题目链接:http://codeforces.com/contest/1301/problem/F
题意:n*m的矩阵,每个点都有颜色,每次你可以去相邻的4个点或者任意颜色和当前点相同的点,问最少多少次从A到B
思路:f[k][i][j]表示(i, j)这点到k颜色的点的最短路径,那么最小花费就是min(f[k][r1][c1] + f[k][r2][c2] + 1)
需要注意的是当进行BFS时首次遇到其他颜色的点时如果当前点没被更新要全部放入队列里,这点是重点。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. #define fi first
  5. #define se second
  6. #define ls rt << 1
  7. #define rs rt << 1|1
  8. #define lson l, mid, ls
  9. #define rson mid + 1, r, rs
  10. #define pll pair<ll, ll>
  11. #define pii pair<int, int>
  12. #define ull unsigned long long
  13. #define pdd pair<double, double>
  14. const int mod = 1e9 + 7;
  15. const int maxn = 1e3 + 10;
  16. const int inf = 0x3f3f3f3f;
  17. int a[maxn][maxn], f[45][maxn][maxn], vis[45];
  18. vector<pii > e[maxn];
  19. int d[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
  20. int n, m;
  21. void bfs(int k)
  22. {
  23. memset(vis, 0, sizeof(vis));
  24. queue<pii > Q;
  25. for(auto it : e[k]) Q.push(it);
  26. while(!Q.empty())
  27. {
  28. auto it = Q.front();
  29. Q.pop();
  30. if(!vis[a[it.fi][it.se]])
  31. {
  32. vis[a[it.fi][it.se]] = 1;
  33. for(auto p : e[a[it.fi][it.se]])
  34. {
  35. if(f[k][p.fi][p.se] != -1) continue;
  36. f[k][p.fi][p.se] = f[k][it.fi][it.se] + 1;
  37. Q.push(p);
  38. }
  39. }
  40. for(int i = 0; i < 4; ++i)
  41. {
  42. int x = it.fi + d[i][0], y = it.se + d[i][1];
  43. if(x < 1 || x > n || y < 1 || y > m || f[k][x][y] != -1)
  44. continue;
  45. f[k][x][y] = f[k][it.fi][it.se] + 1;
  46. Q.push({x, y});
  47. }
  48. }
  49. }
  50. int main()
  51. {
  52. memset(f, -1, sizeof(f));
  53. int k;
  54. scanf("%d%d%d", &n, &m, &k);
  55. for(int i = 1; i <= n; ++i)
  56. {
  57. for(int j = 1; j <= m; ++j)
  58. {
  59. scanf("%d", &a[i][j]);
  60. e[a[i][j]].push_back({i, j});
  61. f[a[i][j]][i][j] = 0;
  62. }
  63. }
  64. for(int i = 1; i <= k; ++i) bfs(i);
  65. int q1;
  66. scanf("%d", &q1);
  67. while(q1--)
  68. {
  69. int r1, c1, r2, c2;
  70. scanf("%d%d%d%d", &r1, &c1, &r2, &c2);
  71. int ans = abs(r2 - r1) + abs(c2 - c1);
  72. for(int i = 1; i <= k; ++i)
  73. {
  74. ans = min(ans, f[i][r1][c1] + f[i][r2][c2] + 1);
  75. }
  76. printf("%d\n", ans);
  77. }
  78. return 0;
  79. }

发表评论

表情:
评论列表 (有 0 条评论,7人围观)

还没有评论,来说两句吧...

相关阅读