a) Algoritmo usaremos un arreglo activo[v] que indica si el algoritmo lo eliminó. Usaremos otro arreglo, donde se indicará la cantidad de aristas entrantes de otros nodos activos. 1) Establecer Activo[v]=true para todo v 2) inicializar indeg[w]= para todo w 3) iniclizar el conjunto S={u e V :indeg[u]=0} 4) Hacer orden topológico vacío O=camino vacío 5) while S distinto vacio{ 6) retirar un nodo u de S y agregarlo al final de O 7) Establecer activo[u]=falso; 8) para cada arista (u,v) saliente de u{ 9) decrementar indeg[v] 10) si indeg[v]=0 agregar v a s. } } 11) si no existe ningún nodo v que no esté activo devolver 0; else{ hacer ciclo vacio; tomar nodo ese nodo construir arreglo visitado[u]=falso para todo u distnto de v tomar u tal que u esta activo y tiene una arista entrante a v. 17) while visitado[u]=true{ establecer visitado[u]=true; u=cualuquier nodo que este activo y tenga una arista entrante hacía el } agregar u al ciclo; v=cualquier nodo que tenga una arista entrante a u y visitado[v]=true while v distinto de u{ agregar v al principio del ciclo v=cualquier nodo que tenga una arista entrante a v y visitado[v]=true } 25) devolver ciclo; } b) Veamos que si G es un DAG, el algoritmo devuelve un orden topológico. Como G es un DAG, sabemos que existe un nodo v sin aristas entrantes. Por lo tanto indeg[v]=0 y el conjunto S será distinto de vacío y se entrará al while. Dentro del while, agregamos ese nodo al final de O, como no tiene aristas entrantes de otros nodos,sabemos que todas las aristas salientes hacia otros nodos que tenga este nodo v, irán hacia adelante en el orden topológico. Lo que hacemos luego es "eliminar" ese nodo de G. Entonces G-{v} seguirá siendo un DAG ya que no se generan ciclos nuevos al eliminar un nodo. Entonces podremos repetir este argumento con G-{v},sabremos que existe un vertice u sin aristas entrantes y por lo anterior estará bien ubicado en el orden topologico. Podremos realizar este proceso hasta que ya no queden mas nodos, por lo tanto construimos un orden topológico Veamos que si G tiene un ciclo, el algoritmo devuelve uno. Como G tiene un ciclo, existe un subconjunto de vertices que tienen todos aristas entrantes de otros nodos,ya que sino G no tendría un ciclo. En el while,se frena cuando el conjunto S es vacio, y esto ocurre, cuando ya no hayan vertices v que cumplan indeg[v]=0, ya que sólo se agregan nodos a v si se pasa esto. Pero en algún momento, como voy eliminando nodos, llegaré a este subconjunto, y no los podré agregar a S, entonces S va a estar vacío pero seguiran habiendo nodos activos Entonces se entrará al si después del while.Como todos los vertices tienen aristas entrantes puedo ir recorriendo hacia atras, hasta que en algún momento llegarué a v devuelta, ya que tenemos una cantidad finita de nodos activos y todos tienen aristas entrantes. Puedo tomar ese v que me aparece dos veces en la busqueda, e ir yendo hacía atrás por aristas entrantes de otros nodos a v, hasta que encontrar v de nuevo,entonces tenemos una secuencia de nodos que empieza y termina en v, por lo tanto es un ciclo.Este se contruye en el último while. c) Asumo que el grafo que me dan, está implementado con listas de adyacencia. El arreglos activo para inicializarlo lleva tiempo O(n) ya que tengo n nodos. Para inicializar indeg, tengo que recorrer para cada uno de los vertices recorro la lista de adyacencia de aristas entrantes, esto es una recorrida por el grafo, y por tanto es O(n+m). El conjunto S, será una lista, entonces para crearla, lleva tiempo O(n). Ya que tengo que recorrer el arreglo indeg que tiene n elementos y la inserción la hago al principio que es O(1). Por lo tanto toda la inicialización es O(m+n). Dentro del primer while, podemos afirmar que cada nodo v es agregado a lo sumo una vez en el conjunto S, ya que se agrega por única vez cuando indeg[v]=0. Entonces este while se ejecuta como mucho n veces. Entonces el ciclo del paso 8 se ejecutara no más de n veces y lleva un tiempo O(nv) por nodo, por lo tanto la cantidad de tiempo total de este paso, como tenemos n nodos es O(m), ya que dentro de él se hacen cosas de tiempo constante. Concluímos que el bloque del paso 5 al 10 es O(m+n). Construir el arreglo visitado lleva tiempo O(n). Para tomar el nodo u, podemos tomar el primer nodo de la lista de adyacencia de v y lleva tiempo O(1). El while del paso 17,voy recorriendo un camino del grafo hasta encontrar un nodo que ya haya sido visitado, pero como tengo n nodos, como mucho tendré que pasar por todos,siempre tomando el primer nodo de la lista de adyacencia de aristas entrantes que esto lleva O(1),entonces el tiempo de este while es O(n), . Análogamente podemos afirmar que el tiempo del útlimo while es O(n) Entonces el tiempo del bloque del paso 17 al 25 es O(n). Por lo tanto el tiempo total del algoritmo es O(m+n)+O(m+n)+O(n)=O(m+n)