当前位置:   article > 正文

无向图中两点(x1,y1)(x2,y2)是否连通(bfs&并查集)两种方法解决(c++)

无向图中两点(x1,y1)(x2,y2)是否连通(bfs&并查集)两种方法解决(c++)

1.bfs

  1. //bfs看两点是否联通
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. // 用于BFS的辅助函数,检查坐标是否在网格内
  5. bool isValid(int x, int y, int n, int m) {
  6. return x >= 0 && x < n && y >= 0 && y < m;
  7. }
  8. // BFS函数,判断两个点是否连通
  9. bool bfs(const vector<vector<int>>& grid, int startX, int startY, int targetX, int targetY) {
  10. int n = grid.size();
  11. int m = grid[0].size();
  12. // 访问标记数组
  13. vector<vector<bool>> visited(n, vector<bool>(m, false));
  14. // 队列用于存储待访问的节点
  15. queue<pair<int, int>> q;
  16. // 初始点入队
  17. q.push({startX, startY});
  18. visited[startX][startY] = true;
  19. while (!q.empty()) {
  20. auto front = q.front();
  21. q.pop();
  22. int x = front.first;
  23. int y = front.second;
  24. // 检查是否到达目标点
  25. if (x == targetX && y == targetY) {
  26. return true; // 连通
  27. }
  28. // 检查上下左右四个方向
  29. vector<pair<int, int>> directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
  30. for (auto& dir : directions) {
  31. int newX = x + dir.first;
  32. int newY = y + dir.second;
  33. if (isValid(newX, newY, n, m) && !visited[newX][newY] && grid[newX][newY] == 0) {
  34. q.push({newX, newY});
  35. visited[newX][newY] = true;
  36. }
  37. }
  38. }
  39. return false; // 不连通
  40. }
  41. int main() {
  42. // 示例网格,0 表示可通行,1 表示障碍物
  43. vector<vector<int>> grid = {
  44. {0, 0, 1, 0, 0},
  45. {0, 1, 0, 1, 0},
  46. {0, 0, 0, 0, 0},
  47. {1, 1, 0, 1, 0},
  48. {0, 0, 0, 0, 0}
  49. };
  50. int startX = 0; // 起始点 x 坐标
  51. int startY = 0; // 起始点 y 坐标
  52. int targetX = 4; // 目标点 x 坐标
  53. int targetY = 4; // 目标点 y 坐标
  54. if (bfs(grid, startX, startY, targetX, targetY)) {
  55. cout << "Points are connected." << endl;
  56. } else {
  57. cout << "Points are not connected." << endl;
  58. }
  59. return 0;
  60. }

2.并查集

  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;
  4. class UnionFind {
  5. private:
  6. vector<int> parent;
  7. vector<int> rank;
  8. int find(int x) {
  9. if (x != parent[x]) {
  10. parent[x] = find(parent[x]); // 路径压缩
  11. }
  12. return parent[x];
  13. }
  14. public:
  15. UnionFind(int n, int m) : parent(n * m), rank(n * m, 1) {
  16. for (int i = 0; i < n * m; ++i) {
  17. parent[i] = i; // 初始时,每个节点的父节点是它自己
  18. }
  19. }
  20. void unionSets(int x, int y) {
  21. int rootX = find(x);
  22. int rootY = find(y);
  23. if (rootX != rootY) {
  24. if (rank[rootX] < rank[rootY]) {
  25. parent[rootX] = rootY;
  26. } else if (rank[rootX] > rank[rootY]) {
  27. parent[rootY] = rootX;
  28. } else {
  29. parent[rootY] = rootX;
  30. rank[rootX]++;
  31. }
  32. }
  33. }
  34. bool isConnected(int x, int y) {
  35. return find(x) == find(y);
  36. }
  37. };
  38. bool isValid(int x, int y, int n, int m) {
  39. return x >= 0 && x < n && y >= 0 && y < m;
  40. }
  41. int main() {
  42. vector<vector<int>> grid = {
  43. {0, 0, 1, 0, 0},
  44. {0, 1, 0, 1, 0},
  45. {0, 0, 0, 0, 0},
  46. {1, 1, 0, 1, 0},
  47. {0, 0, 0, 0, 0}
  48. };
  49. int n = grid.size();
  50. int m = grid[0].size();
  51. int x1 = 0, y1 = 0; // 起始点坐标
  52. int x2 = n - 1, y2 = m - 1; // 目标点坐标
  53. UnionFind uf(n, m);
  54. for (int i = 0; i < n; ++i) {
  55. for (int j = 0; j < m; ++j) {
  56. if (grid[i][j] == 0) {
  57. if (i + 1 < n && grid[i + 1][j] == 0) {
  58. int id1 = i * m + j;
  59. int id2 = (i + 1) * m + j;
  60. uf.unionSets(id1, id2);
  61. }
  62. if (j + 1 < m && grid[i][j + 1] == 0) {
  63. int id1 = i * m + j;
  64. int id2 = i * m + (j + 1);
  65. uf.unionSets(id1, id2);
  66. }
  67. }
  68. }
  69. }
  70. bool connected = uf.isConnected(y1 * m + x1, y2 * m + x2);
  71. cout << "Points (" << x1 << ", " << y1 << ") and (" << x2 << ", " << y2 << ") are "
  72. << (connected ? "connected" : "not connected") << "." << endl;
  73. return 0;
  74. }

3.总结

对于这两种算法,它们的时间复杂度在最坏情况下都可以达到 O(n * m)。然而,在实际应用中,由于并查集的路径压缩优化,它在处理大规模数据时通常比 BFS 更高效。BFS 可能需要遍历更多的节点,尤其是在网格中有大量障碍物时。而并查集则通过减少查找操作的次数来提高效率。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/673276
推荐阅读
相关标签
  

闽ICP备14008679号