Si todo lo que quiere hacer es detectar si la ruta más corta (una que consiste en movimientos monótonamente en la dirección correcta) está bloqueada, entonces está tratando de verificar si los nodos de bloqueo cortan el rectángulo cuyas esquinas están dadas por el nodo de origen y destino en dos regiones diferentes que están desconectadas. Si no es posible un camino más corto desde el origen hasta el destino, entonces cada ruta debe tener algún punto que esté bloqueado.
Supongamos por simplicidad que su punto de inicio está debajo ya la izquierda del punto de destino. En ese caso, encuentre, en O (n), todos los otros puntos que son puntos de obstáculo contenidos en el cuadro delimitador que contiene el punto inicial y final. Ahora quiere ver si hay algún subconjunto de esos nodos que corta el rectángulo en dos partes, una que contiene la esquina inferior izquierda y otra que contiene la esquina superior derecha. Esto es posible si hay una ruta de los nodos de bloqueo desde el lado izquierdo al lado derecho, desde el lado izquierdo al lado inferior, desde el lado superior al lado derecho, o desde el lado superior al lado inferior. Por lo tanto, solo debemos verificar si alguno de estos es posible.
Afortunadamente, esto se puede hacer eficientemente modelando el problema como una búsqueda de gráfico en un gráfico que tiene tamaño O (n), donde n es el número de puntos de bloqueo y no tiene nada que ver con el tamaño del límite caja. Es decir, no importa qué tan separados estén los puntos de prueba, el tamaño del gráfico para buscar depende únicamente de la cantidad de puntos de bloqueo.
El gráfico que desea construir tiene dos partes. Primero, construya un gráfico donde cada punto de bloqueo esté conectado a cada otro punto de bloqueo en el cuadrado de 3x3 que lo rodea. Estos bordes unen los puntos de bloqueo que podrían formar parte de la misma barrera, ya que ningún camino desde la fuente al objetivo podría pasar entre dos puntos de bloqueo unidos por un borde. Ahora, agregue cuatro nuevos nodos que representen la pared superior, la pared izquierda, la pared derecha y la pared inferior y conéctelos a cada nodo adyacente a la pared correspondiente. De esta forma, por ejemplo, una ruta desde el nodo de la pared izquierda hasta el nodo de la pared derecha representaría una serie de nodos de bloqueo que hacen imposible llegar desde el nodo inferior izquierdo al nodo superior derecho.
Este gráfico tiene el tamaño O (n), donde n es el número de nodos de bloqueo, ya que hay O (n) nodos y cada nodo puede tener como máximo 12 bordes, uno para cada uno de los 8 vecinos y potencialmente para cada una de las cuatro paredes. Podrías construirlo en el peor tiempo cuadrático escaneando sobre cada nodo y, para cada otro nodo, ver si son adyacentes. Probablemente haya una mejor manera de hacerlo, pero en este momento no se me ocurre nada.
Ahora que tiene el gráfico, para cada uno de los pares de paredes que, si están conectados, desconectarían el gráfico, ejecute una búsqueda de gráfico en este gráfico entre esos dos nodos de pared. Si existe una ruta, informe que la ruta más corta está bloqueada. De lo contrario, informe que se ha desbloqueado el camino más corto. Estas búsquedas podrían realizarse con un DFS simple, o dado que está ejecutando múltiples búsquedas y solo quiere saber si están conectadas, usando un algoritmo de componentes fuertemente conectados una vez y verificando si hay un par de nodos importantes en el mismo SCC. Cualquiera de los enfoques toma tiempo O (n).
Por lo tanto, el tiempo para resolver este problema es como máximo O (n), siendo el cuello de botella el tiempo requerido para construir el gráfico.
Espero que esto ayude!
En el diagrama de la izquierda, no son todos los caminos de u a v bloqueado? Creo que tendrás que hacer algún tipo de búsqueda para descubrir esto. –
@TedHopp Sí, he mencionado eso en el interior de la descripción (justo debajo) –
Mencionaste que la ruta más corta está bloqueada; no estaba claro (para mí, al menos) que todos los caminos estuvieran bloqueados. –