Algoritmo de etiquetado de tiempo lineal para un árbol?

12

Tengo un árbol no dirigido cuyos vértices quiero etiquetar. Los nodos de la hoja deben etiquetarse como uno. Luego, suponga que las hojas fueron removidas. En el árbol que queda, las hojas deben etiquetarse como dos. Este proceso continúa de la manera obvia hasta que todos los vértices tengan una etiqueta. La razón por la que hago esto es porque quiero almacenar los vértices en una cola y pasar por ellos "las hojas primero". ¿Hay una manera fácil de hacer este tiempo O(n+m) ?

Puedo resolver el problema haciendo un BFS en cada paso. Pero en el peor de los casos, en cada paso que paso por cada vértice, elimino exactamente dos hojas y las pongo en cola. Creo que esto lleva tiempo cuadrático.

Otra idea era encontrar primero todas las hojas y luego hacer un BFS de cada hoja. Esto no me da la solución deseada. Por ejemplo, considere un tipo de "gráfico de corona" como en la figura a continuación. Se muestra la solución deseada, pero el lanzamiento de un BFS desde cada hoja daría como resultado solo dos etiquetas utilizadas.

ingrese la descripción de la imagen aquí

Idealmente, el algoritmo de tiempo lineal también sería fácil de explicar e implementar.

Bob Whiz
fuente

Respuestas:

8

Árboles sin raíces

O(E+VlogV)

  • Ponga todos los vértices en una cola de prioridad, siendo su prioridad su grado.
  • Mientras la cola no está vacía:
    • v10
    • σ(v)=1+maxσ(u)uv
    • Reste de la prioridad del vecino único restante de (si lo hay).1u

De hecho, realmente no necesitamos una cola prioritaria, y este algoritmo puede implementarse usando una cola simple en el tiempo :O(E+V)

  • Inicialice una matriz de longitud con los grados de todos los vértices.V
  • Inicialice otra matriz de longitud con "vivo".V
  • Ir una vez a través de la primera matriz y empujar todos los vértices de grado a una cola.1
  • Mientras la cola no está vacía:
    • Pop un vértice .v
    • Let , donde va sobre todos los vecinos originales de .σ(v)=1+maxσ(u)uv
    • Marque como "muerto".v
    • Si tiene algún vecino "vivo" , reste del grado de .vu1u
    • Si el nuevo grado de es , empujar a la cola.u1u

Árboles enraizados

Use DFS en su lugar. Aquí hay un boceto del algoritmo.

  • Dado un nodo , si es una hoja, establezca .vvd(v)=1
  • Si no es una hoja, ejecute el algoritmo en todos sus elementos secundarios y luego deje que , donde va sobre el conjunto de todos los elementos secundarios.vd(v)=1+maxd(u)u

Ejecutas este algoritmo en la raíz.

Yuval Filmus
fuente
¿Es esto correcto? Considere el árbol 1-> 2-> 3-> 4-> 5, donde 1 es la raíz. 2 debería obtener la etiqueta 1, pero le das 3? ¿O por niños te refieres a vecinos? ¿Desde qué nodo comenzamos el dfs desde entonces?
Knoothe
Mi implementación está "desactivada por uno", pero de acuerdo con su descripción, debería obtener la etiqueta , ya que debe eliminar , luego , luego , y solo entonces convierte en una hoja. 245432
Yuval Filmus
No hice la pregunta :-). Interpreté la pregunta como: Un árbol no dirigido. Rotula todas las hojas. Borra los. Recurrir en el árbol resultante. En ese caso, el árbol es en realidad 1-2-3-4-5, Paso 1, borra 1 y 5, luego 2 y 4 y luego 3. Vea el párrafo sobre "gráfico de corona". Este es uno de los algoritmos clásicos para encontrar el centro de un árbol.
Knoothe
1 no es una hoja. Está muy lejos de ser una hoja, es la raíz. Interpreté la pregunta como dirigida a árboles enraizados. Quizás deberíamos esperar a que el OP responda.
Yuval Filmus
2
@YuvalFilmus, solo para tirar mis 2 centavos, ¿no debería ser ? Las hojas son , si las borra entonces las nuevas hojas deben ser , por lo que es una especie de medida de cuántas capas tiene que eliminar antes de que el vértice se convierte en una hoja. Con min, cualquier vértice adyacente a una hoja obtiene 2, pero puede no convertirse en una hoja cuando se eliminan las hojas. Esa oración tenía demasiadas hojas. Necesito una escoba 1+max{d(u)}12
Luke Mathieson
2

Una respuesta directa es la siguiente:

  • Convierta esto en un gráfico dirigido, donde tengamos una arista desde cada nodo hasta su padre . Tenga en cuenta que obtiene un dag (gráfico acíclico dirigido).(u,v)uv

  • Topológicamente ordenar el gráfico.

  • Escanee los vértices, en orden ordenado. Etiquete cada vértice con una más que la mayor de las etiquetas en sus predecesores. Como estamos escaneando en orden topológico, todos los predecesores de ya habrán recibido una etiqueta antes de intentar etiquetar .vv

Cada uno de estos pasos se puede realizar en tiempo , por lo que el tiempo total de ejecución es . Menciono este enfoque alternativo solo en caso de que te resulte conceptualmente más fácil de entender que la respuesta de Yuval.O(n+m)O(n+m)

DW
fuente