如何检查网格内的点是否垂直/水平连接?(彼此相距1)
How do you check if points within a grid are connected vertically/horizontally? (1 away from each other)
让我们只用 1 因为有一个点,如果没有,则用 0
。例如,网格:
0 00 0 0
1 1 11 1
0 00 0 0
1 1 11 1
不会连接在一起,而
0 01 0 0
01 1 0 0
0 0 11 0
0 00 1 1
是。
我觉得使用像BFS这样的东西对于可能应该相当简单的东西来说效率非常低;还有其他选择吗?
此类问题的最佳渐近复杂度来自使用秩和路径压缩的联合查找算法。
Union find 将每个新点与组名称相关联,该组名称是唯一的、取自左侧或顶部邻居的,或者统一组(通过从一个组链接到另一个组)。
最后,所有初始唯一组的所有父组都指向同一项目,在这种情况下,集合是连接的。
进一步阅读 c++ 源代码
图像处理的进一步阅读
#include "catch.hpp"
#include <vector>
template <typename T>
T parent(std::vector<T> &links, T item)
{
if (item == 0)
return item;
while (links[(size_t)item - 1] != item)
item = links[(size_t)item - 1];
// Should implement path compression
return item;
}
template <typename T, int N, int M>
bool is_connected(T(&array)[N][M])
{
// Assumption is that the type T is large enough to hold N*M/2 distinct entries
// Thus we can use/modify the array itself to record (roots) of distinct labels
// Of course we could copy the array into a vector of type size_t
std::vector<T> parents;
for (auto j = 0; j < N; j++)
{
for (auto i = 0; i < M; i++)
{
T ¤t = array[j][i];
if (!current)
continue;
T left = i ? parent(parents, array[j][i - 1]) : 0;
T above = j ? parent(parents, array[j - 1][i]) : 0;
if (left == 0)
{
if (above)
current = above;
else
parents.emplace_back(current = (T)(parents.size() + 1));
}
else
{
// Todo: implement rank based selection of joining the sets
current = left;
if (above != 0 && above != left)
parents[(size_t)above - 1] = left;
}
}
}
// Check that all intermediate disjoint sets have now a single root
if (parents.size() == 0)
return false; // is empty set connected or not?
auto last_item = parents.back();
auto root = parent(parents, last_item);
parents.pop_back();
for (auto &group : parents)
{
if (root != parent(parents, group))
return false;
}
return true;
}
SCENARIO("Is connected")
{
int arr[4][4] = {
{ 1, 0, 1, 0 },
{ 1, 0, 1, 0 },
{ 1, 0, 1, 0 },
{ 1, 1, 1, 1 }
};
auto foo = is_connected(arr);
CHECK(foo == true);
arr[3][1] = 0;
CHECK(is_connected(arr) == false);
}
BFS或DFS确实是正确的解决方案。剩下的只是利用直线网格(栅格)的属性以更有效的方式实现此类搜索算法,最好比"直接"实现更有效。例如,一些经典的 4 向光栅扫描线泛洪填充算法是在网格中搜索连接组件的好方法(请参阅"扫描线填充"部分)。
相关文章:
- 当套接字连接断开时检测C/C++Unix
- QTableView:endMoveRows在模型中重置水平页眉大小
- QScrollArea:由垂直滚动条引起的水平滚动条
- 无法在windows上使用mingw将sqlite3与c连接
- 到连接组件算法的问题(递归)
- QTcpSocket在不阻塞GUI的情况下重新连接到服务器
- 无法在C++中建立与MySQL数据库的连接
- PC中的程序和PHONE中的本机描述应用程序之间的数据连接
- 在Qt Creator中,如何在连接到正在运行的进程后查看控制台输出
- 连接 dockerized 模型和 dockerized 数据库时出现"无法 SQLConnect"错误
- 使用 bfs 解决连接组件问题时得到错误的答案
- 在C++的两个字符串中连接以逗号分隔的唯一值
- 如何修复valgrind启动时的致命错误(与libc6-dbg和libc6-dbg:i386连接)
- C++应用程序 MySQL odbc 数据库连接错误:在引发"otl_tmpl_exception<>"实例后终止调用
- OSX蓝牙打开RFCOMMChannelAsync声称已连接,但未建立连接,并且从未调用过委托
- 在 libcurl 连接池中预创建连接
- 套接字连接"Operation not permitted"错误,甚至使用升压/平发器根.cpp
- libcurl 和 DNS ttl 中的内部连接管理
- 如何应用 libcurl 的持久连接选项
- 如何检查网格内的点是否垂直/水平连接?(彼此相距1)