1203 - Pontes de São Petersburgo
Uma mistura de conhecimento em grafos com programação dinâmica.
Last updated
Uma mistura de conhecimento em grafos com programação dinâmica.
Last updated
Recebemos a descrição de uma cidade, que possui R regiões e K pontes que ligam determinadas regiões e gostaríamos de saber se é possível selecionar um certo grupo de regiões tal que o número de pontes total seja K, contando duplicatas. Essas duas últimas palavras são importantes, pois caso não contássemos, a solução seria trivial, se escolhêssemos todas as regiões, teríamos K pontes entre todo o mundo. Mas o que quer dizer contar duplicatas nesse contexto? Significa que, se escolhermos as regiões A e B e elas compartilharem uma ponte, essa ponte na verdade vai ser contada duas vezes, uma pela escolha de A e outra pela escolha de B.
Com isso, é preciso pensarmos em qual abordagem podemos implementar para a escolha das regiões corretamente de forma a termos K pontes entre elas. Note que, para cada região, temos uma escolha: incluí-la ou não no grupo de regiões que compartilham K pontes entre si. Com isso, temos um problema que pode ser interpretado da seguinte forma: para uma região i onde eu já tenho x pontes, vale a pena eu incluir minha região, trazendo minhas pontes adjacentes às x pontes já existentes na solução, ou não vale a pena?
Isso é basicamente o princípio da programação dinâmica, onde tentamos compor nossa solução através de soluções anteriores. Com isso, teremos uma recorrência da seguinte forma:
onde próxima se refere à próxima região e grau(região) ao número de pontes que incidem na região que estamos olhando. Basicamente, nossa recorrência nos diz que é possível ter um grupo de regiões onde o número de pontes é igual a K se só seguirmos para a próxima região sem acrescentar pontes (caso onde a região não é escolhida) ou se seguirmos para a próxima região acrescentando nossa quantidade de pontes (caso em que a região é escolhida). Temos também nossos casos base:
Se a variável pontes
for igual a K, retornar verdadeiro.
Se a variável pontes
for maior que K, retornar falso.
Se a região for inválida, retornar falso. Esse caso vai se tornar mais claro no código.
Logo, tudo o que resta é saber se nosso espaço de busca é pequeno o bastante para conseguirmos fazer a memorização da nossa programação dinâmica (na verdade, a gente deveria ter feito isso no começo). São 100 regiões no máximo com no máximo 4950 pontes, o que dá para armazenar em uma matriz, então tudo certo. Então agora podemos seguir com o código, apenas lembrando que a chamada externa é T(1, 0) (começando na região 1 com, por enquanto, 0 pontes na solução).
Repare que não foi necessário implementar o grafo na nossa solução, apenas o número de graus de cada vértice (o número de pontes em cada região).