Solução Informática – Nível Avançado – Semana 29

por

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 $$1$$ para $$i$$.
  • O segundo Dijkstra vai dizer qual é o menor caminho de $$1$$ para $$i$$ usando um cupom.

Para o primeiro Dijkstra, a transição vai ser o seguinte:

Se estamos no vértice $$u$$ e queremos ir para $$v$$, vemos se a distância de $$1$$ para $$v$$ já calculada é maior que a distância de $$1$$ para $$u$$ mais o peso da aresta de $$u$$ para $$v$$ (Ou seja, se $$dist[v] > dist[u] + w$$). Se for verdade, atualizamos o valor de $$dist[v]$$ e colocamos $$v$$ na priority queue.

Para o segundo Dijkstra, se estamos no vértice $$u$$ e queremos ir para $$v$$, temos duas possibilidades:

  1. Se já usamos o cupom no caminho de $$1$$ para $$u$$, logo, vemos se a distância de $$1$$ para $$v$$ já calculada é maior que a distância de $$1$$ para $$u$$ mais o peso da aresta de $$u$$ para $$v$$ (Ou seja, se $$dist2[v] > dist2[u] + w$$). Se for verdade, atualizamos o valor de $$dist2[v]$$ e colocamos $$v$$ na priority queue.
  2. Se ainda não usamos o cupom, vamos usar ele na aresta de $$u$$ para $$v$$, portanto, vemos se a distância de $$1$$ para $$v$$ com cupom já calculada é maior do que a distância sem o cupom de $$1$$ para $$u$$ mais o peso da aresta de $$u$$ para $$v$$ dividido por $$2$$ (Ou seja, se $$dist2[v] > dist[u] + w/2$$). Se for verdade, atualizamos o valor de $$dist2[v]$$ e colocamos $$v$$ 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 $$n$$ para o segundo Dijkstra.

Recomendamos que você tente implementar o problema antes de ver o código. Veja a implementação nesse link.