Solução por Lúcio Figueiredo
Conhecimento prévio necessário:
Seja um grafo que possui vértices e arestas direcionadas, formadas ao ligar os dois vértices e de cada pedido . Defina o grafo como um grafo que usa a menor quantidade de arestas direcionadas necessárias de modo a satisfazer todos os pedidos.
Defina componente fracamente conexa como um conjunto de vértices em um grafo direcionado tal que, para cada par de vértices na mesma componente, existe um caminho de para ou de para .
Perceba que, para cada pedido , os vértices e estão na mesma componente fracamente conexa em e em . Logo, os vértices de cada componente fracamente conexa de são formados pela união de vértices de componentes fracamente conexas em .
Vamos assumir que possui as mesmas componentes fracamente conexas que , ou seja, que nenhuma união de componentes foi realizada. Iremos provar, posteriormente, que não é ótimo realizar a união de componentes de para formar . Vamos, então, calcular o número mínimo de arestas necessárias em cada componente de , analisando as componentes de .
Para cada componente de , vamos analisar dois casos:
Caso 1: é acíclica. Neste caso, vamos realizar uma ordenação topológica em . Seja tal ordenação topológica, onde é o -ésimo vértice na ordenação. Se criarmos uma aresta indo de para para , conseguimos realizar todos os pedidos na componente, já que para todo pedido , possui índice menor que na ordenação topológica. Logo, conseguimos satisfazer os pedidos nesta componente com arestas, que é um valor ótimo, já que a quantidade mínima de arestas em uma componente fracamente conexa é .
Caso 2: possui um ciclo. Neste caso, perceba que a quantidade mínima de arestas necessárias é , já que toda componente fracamente conexa cíclica possui pelo menos arestas. Assim, podemos simplesmente ligar os vértices de em um "círculo"; ou seja, sendo os vértices de , podemos simplesmente criar uma aresta de para para todo e uma aresta adicional de para . Desta forma, com arestas, ligamos os vértices da componente de forma que todo vértice consegue alcançar qualquer outro vértice da componente, e portanto, todos os pedidos serão satisfeitos.
Usando as observações já feitas, concluímos que o número mínimo de arestas em é igual a , onde o somatório percorre todas as componentes fracamente conexas de e é igual a se é acíclica e caso contrário.
No entanto, as observações acima assumem que nenhuma componente de será formada pela união de componentes de . Provaremos a seguir que, de fato, nunca é ótimo unir duas componentes de para formar .
Prova: Vamos realizar uma prova por absurdo, ou seja, suponha que existem componentes fracamente conexas em tal que é ótimo unir os vértices em tais componentes para formar alguma componente fracamente conexa em . Vamos dividir a prova em dois casos:
Caso 1: Nenhuma das componentes () possui um ciclo. Neste caso, ao unir as componentes , a componente resultante possuirá vértices. Logo, como a componente será acíclica, concluímos que a quantidade mínima de arestas que satisfazem os pedidos desta nova componente é . Por outro lado, caso esta união não fosse realizada, a quantidade total de arestas necessárias para cada componente seria igual a , que é estritamente menor que . Logo, chegamos em um absurdo.
Caso 2: Alguma das componentes de () possui um ciclo. Neste caso, ao unir as componentes , a componente resultante possuirá vértices. Como a componente possuirá um ciclo, a quantidade mínima de arestas que satisfazem os pedidos desta nova componente é . Por outro lado, caso esta união não fosse realizada, a quantidade total de arestas necessárias para cada componente seria igual a , que é menor ou igual a . Logo, chegamos em um absurdo, pois realizar a união não reduzirá a quantidade de arestas necessárias em .
Logo, provamos a afirmação de que não é ótimo realizar a união de componentes de para formar .
A complexidade final da solução é , pois conseguimos encontrar componentes fracamente conexas utilizando DFSs, e para checar se uma componente é acíclica, podemos verificar se existe uma ordenação topológica em tal componente.
Confira o código para melhor entendimento: