2

Consider this problem:

There's a square grid defined, each tile being either passable (1) or impassable (0). At first, we have a simply connected space in the grid with an impassable border, like this:

enter image description here

We then start placing impassable obstacles of various dimensions (e.g. 1x1, 2x2,..) into the passable space. After each obstacle is placed, we need to test whether the remaining passable space is still connected (i.e. make sure we didn't split the passable space in two or more disconnected spaces). Tiles are connected diagonally, too.

The point is that after every obstacle placement, every remaining passable tile has a path that connects it to EVERY other remaining passable tile.

I'm aware of the possibility of searching for paths between possibly disconnected points, but I'm afraid that might be too inefficient. What I'm interested in is doing this testing as fast as possible.

Thanks for any help!

amit
  • 175,853
  • 27
  • 231
  • 333
vedran
  • 751
  • 1
  • 5
  • 16

2 Answers2

4

Implement a flood fill algorithm. As a side effect of performing the fill, count the number of squares filled. After placing your obstacles perform another flood fill starting from any open square and compare the number of filled squares to the original number minus the number of squares placed as obstacles. If they are not the same, you have disconnected regions.

Snowhare
  • 952
  • 5
  • 7
1

Wikipedia says that this can be done in amortized O(|V|) time using disjoint-set data structures, where V is the number of elements in the passable space (the second paragraph of that section). The citation is to this paper.

This is the same asymptotic complexity as Benjamin's answer and is presumably harder to implement, so I'd go with that. :)

Community
  • 1
  • 1
Danica
  • 28,423
  • 6
  • 90
  • 122
  • 2
    This solution fits when you *add* vertices not *remove* them. However - if it can somehow be utilized for removing edges, it will be much more efficient then `O(|V|)`. You will have pre-processing of `O(|V|)` for the first time, but for each obstacle added - it will be much faster then `O(|V|)`. It will be `O(alpha(n))` where `alpha` is the reverse [ackerman function](http://en.wikipedia.org/wiki/Ackermann_function), whcih is less then 4 for every practical input. But I am not sure if you can utilize it to deleting edges. – amit Apr 01 '12 at 23:01
  • Good point, I was reading sloppily. I don't actually know if there's a way to use union-find (with its inverse-Ackermann runtime) for removing edges....it would need some kind of trick like constructing a dual graph (not that, that doesn't work). – Danica Apr 01 '12 at 23:53