让我们只使用1作为有一个点,如果没有则使用0。
例如,网格:
0 0 0 0 0
1 1 1 1 1
0 0 0 0 0
1 1 1 1 1
不会连接在一起,而
0 0 1 0 0
0 1 1 0 0
0 0 1 1 0
0 0 0 1 1
是
我觉得好像使用像BFS这样的东西对于一些可能相当简单的东西来说效率非常低;还有其他选择吗?
答案 0 :(得分:1)
BFS或DFS确实是正确的解决方案。其余的只是利用直线网格(栅格)的特性以更有效的方式实现这种搜索算法,优选地比“直接”实现更有效。例如,某些经典的4向栅格scanline flood-fill algorithm是搜索网格中连接组件的好方法(请参阅“扫描线填充”部分)。
答案 1 :(得分:1)
这类问题的最佳渐近复杂性来自使用秩和路径压缩的并集查找算法。
Union查找每个新点与一个组名称相关联,该组名称是唯一的,取自左侧或顶级邻居,或统一组(通过建立从一个组到另一个组的链接)。 / p>
最后,所有最初唯一群组的所有父母都指向相同的项目,在这种情况下,该集合已连接。
Further reading with c++ source code
Further reading for image processing
#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);
}