Buenas, queria compartir mi solucion para saber si la demostracion es correcta, ya que creo que esta un poco floja, el pseudocodigo es
(indeg cuenta la cantidad de aristas entrantes a un nodo)
El algoritmo termina pues los "Para cada" siempre terminan, la unica fuente de bucle infinito posible es el Mientras, aunque en cada iteracion se elimina un elemento del conjunto S,
como ademas solo se agregan vertices y hay tan solo de ellos, concluimos que itera a lo sumo veces. Y por tanto todo el algoritmo termina.
Correccion: el algoritmo devuelve un OT si y solo si G tiene un OT
(=>) El algoritmo es analogo al propuesto por el libro (me gustaría saber si esto es una justifiacion suficiente)
(<=) Probaré el contrarreciproco, es decir, el algoritmo no devuelve OT => G no tiene OT
Si el algoritmo no devuelve un OT devuelve un ciclo formado por los nodos v tales que indag[v] != 0, sean estos como cada uno recibe al menos una arista
puedo recorrerlos hacia atras k+1 veces, y debo haber visitado un nodo 2 veces y por tanto halle un ciclo, entonces G no es un DAG y por tanto no admite un OT.
Ahora que demostramos la proposicion anterior, podemos observar que es equivalenta a probar
el algoritmo devuelve un ciclo si y solo si G tiene un ciclo
Pues la negacion de "el algoritmo devuelve un OT" es "el algoritmo devuelve un ciclo", por el If final.
Y la negacion de "G tiene un OT" es, claramente, "G no tiene un OT", que implica que G sea cíclico, pues G es un DAG si y solo si tiene un OT (resultado del libro).
(c) Veamos que admite una implementacion en O(m + n)
Podemos usar la representacion de lista de adyacencia para el grafo G, recorriendo el conjunto de nodos y aristas, para O(1) por cada elemento podemos crear el grafo en O(m+n)
El primer "Para cada" es O(n), el bucle "Mientras" es O(n) por el mismo argumento que la terminacion y el "Para cada" dentro del "Mientras" se ejecuta a lo sumo m veces sobre todas
las iteraciones del bucle y por tanto podemos concluir que todo el algoritmo es O(m+n)