Cómo minimizar el diámetro de un árbol si puede cambiar como máximo un borde del árbol

Esto es bastante similar a lo que propone Anonymous, pero espero que sea un poco más simple de entender. Supongo que ya sabe cómo calcular el diámetro de todos los subárboles enraizados de un árbol y cómo encontrar el centro de un árbol.

Intentaremos eliminar cada borde. Eliminar un borde nos deja con dos árboles, T1 y T2. Para volver a conectar estos árboles, debemos agregar un borde entre los centros. Observe que esto hace que el diámetro del árbol reconectado sea el máximo de diámetro (T1), diámetro (T2), 1 + techo (diámetro (T1) / 2) + techo (diámetro (T2) / 2). Podemos ver aquí por qué la conexión de los centros es óptima; cualquier otra opción de punto de conexión en T1 tendría una ruta mayor que el techo (diámetro (T1) / 2) dentro de T1 saliendo de él (y lo mismo para T2).

Una vez que sepamos qué borde eliminar, podemos agregar un borde entre los centros de T1 y T2.

Como todos los cálculos de diámetro y los dos cálculos centrales se pueden hacer en tiempo lineal, el algoritmo general es lineal. Si solo necesita calcular el mejor diámetro obtenible (y no qué bordes eliminar y agregar), ni siquiera necesita hacer ningún cálculo de centro de árbol.

Lo siento, permítanme comenzar con esto diciendo que generalmente no hago esto, por lo que la explicación puede ser aproximada y puede ser incorrecta, pero creo que las ideas deberían ser modificables a la solución. También partes de esto se vuelven más simples con la búsqueda binaria si NlgN está bien.

Considere todos los bordes como el posible eliminado:
Arregla la raíz del árbol. Para cada borde, al eliminarlo, se divide en 2 subárboles. El nuevo borde óptimo conecta los centros de los 2 subárboles. Intente eliminar bordes como dfs desde la raíz. Esto reduce la cuestión de encontrar los centros / radios y el diámetro de todos los subárboles, así como mantener esto para el barrido DFS hacia abajo.

Subárboles:
El diámetro es un DP estándar. Centro / radios es más molesto. Se basa en que el centro se puede encontrar moviéndolo constantemente hacia el subárbol con la ruta más larga (ver más abajo). Afirmo que puede mantener el centro en lineal mirando el subárbol que tiene el camino más largo hacia una hoja. Como ya conocemos el centro de ese subárbol y el nuevo centro tiene que estar en el camino desde ese centro hasta la raíz de nuestro subárbol actual: deberíamos poder moverlo hacia arriba hasta que sea el nuevo centro. Así que sigue moviéndote mientras lo comparas con la segunda ruta más larga desde la nueva raíz. Esto debería ser O (N) total ya que no se visita ningún nodo más de una vez.

Para DFS hacia abajo:
El diámetro es fácil. Radii nuevamente: voy a afirmar que el centro de un árbol siempre estará en algún diámetro, específicamente cerca del punto medio de uno. Prueba: cualquier cosa que no esté en el diámetro tiene una peor distancia a uno de los puntos finales del diámetro, y en el diámetro uno de los puntos medios es el mejor. Entonces, si arraigamos el árbol en uno de los nodos del diámetro, podemos mantener que el diámetro siempre está en la parte superior del barrido. Ahora, si nuestro borde de corte no está en el diámetro, ya conocemos los radios. De lo contrario: podemos hacer exactamente lo mismo para los subárboles, moviendo lentamente el centro hacia adelante. Como siempre está en una línea fija, será O (N) máx.

Radios partes:
Un algoritmo para encontrar el radio / centro de un árbol es elegir un nodo aleatorio y observar las rutas más largas a una hoja en todos los subárboles que son hijos de ese nodo. Luego, elija al niño en el subárbol con el camino más largo. Esto se modifica para funcionar para esta pregunta.

Resumen:
1) Encuentra el diámetro del árbol. Fijar la raíz en algún lugar de diámetro. EN)
2) Buscar para todos los nodos: longitud de ese nodo a una hoja en su subárbol, la más larga de estas longitudes (y qué hijo) para todos los hijos y lo mismo para el segundo más largo. Alternativamente, solo encuentre esta información para todos y ordene con countort. EN)
3) Encuentra el diámetro de todos los subárboles. EN)
4) Encuentra el centro de todos los subárboles. Tome el centro del subárbol con la longitud más larga (que se encuentra arriba). Mueva el centro hacia arriba (llame donde está actualmente: c) siempre que la ruta de c a nuestra raíz + segunda ruta más larga sea> la ruta más larga del subárbol de c. O (N) amortizado ya que no se visita ningún nodo más de una vez.
5) Barrer hacia abajo. Mantener el diámetro O (N)
6) Para todos los cortes no en diámetro. El radio es conocido, no es un problema.
7) De lo contrario, encuentre el centro de partida asumiendo que los cortes están en el diámetro. Muévelo más cerca de 4 a medida que nos movemos al

Perdón por el boceto.

More Interesting

Tiene una lista vinculada en la que cada nodo es otra lista vinculada. ¿Cómo encuentra el elemento Kth más exclusivo entre todos los nodos en el momento más óptimo?

¿Hay algún algoritmo que sea más rápido que log (n)?

¿Qué método es el más adecuado para resolver problemas de programación de enfermería, programación dinámica o algoritmos genéticos, y por qué?

¿Cuál es el inverso matemático de 2 ^ N?

¿Por qué la agrupación aleatoria al iterar sobre ella y cambiarla por un elemento aleatorio entre 0 y el último elemento de la matriz no produce una barajadura distribuida uniformemente?

¿Estamos utilizando los mismos algoritmos de inteligencia artificial de los años 90 con mejores procesadores?

Si un generador de números aleatorios generara 1600 números del 1 al 16, ¿cuántos habría de cada número?

¿Cuáles son los mejores algoritmos híbridos para el filtrado colaborativo y basado en contenido?

¿Es una buena idea modelar otras estructuras de datos después de STD :: Vector?

¿Cómo funciona Junglee?

Programación competitiva: dado un polígono y tres cuadrados congruentes alineados con el eje, ¿puede determinar en tiempo polinómico si el polígono puede cubrirse por completo de manera que los tres cuadrados, que pueden superponerse, cubran una cantidad igual de área en el polígono?

¿Hay un libro sobre estructuras de datos PHP y algoritmos?

¿Encuentra el número de fila y el número de columna donde 20096 ocurre en una matriz triangular?

Cómo imprimir una cadena usando un puntero

¿Qué algoritmo usa Google Knowledge Graph? ¿Con qué precisión funciona?