Escrito por Caique Paiva
Conhecimento prévio necessário:
Vamos fazer dois Dijkstra, e eles vão funcionar da seguinte maneira:
- O primeiro Dijkstra vai ser normal, dizendo qual é o menor caminho de para .
- O segundo Dijkstra vai dizer qual é o menor caminho de para usando um cupom.
Para o primeiro Dijkstra, a transição vai ser o seguinte:
Se estamos no vértice e queremos ir para , vemos se a distância de para já calculada é maior que a distância de para mais o peso da aresta de para (Ou seja, se ). Se for verdade, atualizamos o valor de e colocamos na priority queue.
Para o segundo Dijkstra, se estamos no vértice e queremos ir para , temos duas possibilidades:
- Se já usamos o cupom no caminho de para , logo, vemos se a distância de para já calculada é maior que a distância de para mais o peso da aresta de para (Ou seja, se ). Se for verdade, atualizamos o valor de e colocamos na priority queue.
- Se ainda não usamos o cupom, vamos usar ele na aresta de para , portanto, vemos se a distância de para com cupom já calculada é maior do que a distância sem o cupom de para mais o peso da aresta de para dividido por (Ou seja, se ). Se for verdade, atualizamos o valor de e colocamos na priority queue.
Então primeiro fazemos o primeiro Dijkstra normal, e depois fazemos outro usando as informações do primeiro Dijkstra também, e dai é só retornar a resposta de para o segundo Dijkstra.
Recomendamos que você tente implementar o problema antes de ver o código. Veja a implementação nesse link.