赞
踩
- //bfs看两点是否联通
- #include <bits/stdc++.h>
- using namespace std;
-
- // 用于BFS的辅助函数,检查坐标是否在网格内
- bool isValid(int x, int y, int n, int m) {
- return x >= 0 && x < n && y >= 0 && y < m;
- }
-
- // BFS函数,判断两个点是否连通
- bool bfs(const vector<vector<int>>& grid, int startX, int startY, int targetX, int targetY) {
- int n = grid.size();
- int m = grid[0].size();
-
- // 访问标记数组
- vector<vector<bool>> visited(n, vector<bool>(m, false));
-
- // 队列用于存储待访问的节点
- queue<pair<int, int>> q;
-
- // 初始点入队
- q.push({startX, startY});
- visited[startX][startY] = true;
-
- while (!q.empty()) {
- auto front = q.front();
- q.pop();
-
- int x = front.first;
- int y = front.second;
-
- // 检查是否到达目标点
- if (x == targetX && y == targetY) {
- return true; // 连通
- }
-
- // 检查上下左右四个方向
- vector<pair<int, int>> directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
- for (auto& dir : directions) {
- int newX = x + dir.first;
- int newY = y + dir.second;
-
- if (isValid(newX, newY, n, m) && !visited[newX][newY] && grid[newX][newY] == 0) {
- q.push({newX, newY});
- visited[newX][newY] = true;
- }
- }
- }
-
- return false; // 不连通
- }
-
- int main() {
- // 示例网格,0 表示可通行,1 表示障碍物
- vector<vector<int>> grid = {
- {0, 0, 1, 0, 0},
- {0, 1, 0, 1, 0},
- {0, 0, 0, 0, 0},
- {1, 1, 0, 1, 0},
- {0, 0, 0, 0, 0}
- };
-
- int startX = 0; // 起始点 x 坐标
- int startY = 0; // 起始点 y 坐标
- int targetX = 4; // 目标点 x 坐标
- int targetY = 4; // 目标点 y 坐标
-
- if (bfs(grid, startX, startY, targetX, targetY)) {
- cout << "Points are connected." << endl;
- } else {
- cout << "Points are not connected." << endl;
- }
-
- return 0;
- }
- #include <iostream>
- #include <vector>
- using namespace std;
-
- class UnionFind {
- private:
- vector<int> parent;
- vector<int> rank;
-
- int find(int x) {
- if (x != parent[x]) {
- parent[x] = find(parent[x]); // 路径压缩
- }
- return parent[x];
- }
-
- public:
- UnionFind(int n, int m) : parent(n * m), rank(n * m, 1) {
- for (int i = 0; i < n * m; ++i) {
- parent[i] = i; // 初始时,每个节点的父节点是它自己
- }
- }
-
- void unionSets(int x, int y) {
- int rootX = find(x);
- int rootY = find(y);
- if (rootX != rootY) {
- if (rank[rootX] < rank[rootY]) {
- parent[rootX] = rootY;
- } else if (rank[rootX] > rank[rootY]) {
- parent[rootY] = rootX;
- } else {
- parent[rootY] = rootX;
- rank[rootX]++;
- }
- }
- }
-
- bool isConnected(int x, int y) {
- return find(x) == find(y);
- }
- };
-
- bool isValid(int x, int y, int n, int m) {
- return x >= 0 && x < n && y >= 0 && y < m;
- }
-
- int main() {
- vector<vector<int>> grid = {
- {0, 0, 1, 0, 0},
- {0, 1, 0, 1, 0},
- {0, 0, 0, 0, 0},
- {1, 1, 0, 1, 0},
- {0, 0, 0, 0, 0}
- };
-
- int n = grid.size();
- int m = grid[0].size();
- int x1 = 0, y1 = 0; // 起始点坐标
- int x2 = n - 1, y2 = m - 1; // 目标点坐标
-
- UnionFind uf(n, m);
- for (int i = 0; i < n; ++i) {
- for (int j = 0; j < m; ++j) {
- if (grid[i][j] == 0) {
- if (i + 1 < n && grid[i + 1][j] == 0) {
- int id1 = i * m + j;
- int id2 = (i + 1) * m + j;
- uf.unionSets(id1, id2);
- }
- if (j + 1 < m && grid[i][j + 1] == 0) {
- int id1 = i * m + j;
- int id2 = i * m + (j + 1);
- uf.unionSets(id1, id2);
- }
- }
- }
- }
-
- bool connected = uf.isConnected(y1 * m + x1, y2 * m + x2);
- cout << "Points (" << x1 << ", " << y1 << ") and (" << x2 << ", " << y2 << ") are "
- << (connected ? "connected" : "not connected") << "." << endl;
-
- return 0;
- }
对于这两种算法,它们的时间复杂度在最坏情况下都可以达到 O(n * m)
。然而,在实际应用中,由于并查集的路径压缩优化,它在处理大规模数据时通常比 BFS 更高效。BFS 可能需要遍历更多的节点,尤其是在网格中有大量障碍物时。而并查集则通过减少查找操作的次数来提高效率。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。