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.