Your SlideShare is downloading. ×
0
Treinamento para Competições de Programacão - Single-Source Shortest Paths: Dijkstra e Bellman-Ford
Treinamento para Competições de Programacão - Single-Source Shortest Paths: Dijkstra e Bellman-Ford
Treinamento para Competições de Programacão - Single-Source Shortest Paths: Dijkstra e Bellman-Ford
Treinamento para Competições de Programacão - Single-Source Shortest Paths: Dijkstra e Bellman-Ford
Treinamento para Competições de Programacão - Single-Source Shortest Paths: Dijkstra e Bellman-Ford
Treinamento para Competições de Programacão - Single-Source Shortest Paths: Dijkstra e Bellman-Ford
Treinamento para Competições de Programacão - Single-Source Shortest Paths: Dijkstra e Bellman-Ford
Treinamento para Competições de Programacão - Single-Source Shortest Paths: Dijkstra e Bellman-Ford
Treinamento para Competições de Programacão - Single-Source Shortest Paths: Dijkstra e Bellman-Ford
Treinamento para Competições de Programacão - Single-Source Shortest Paths: Dijkstra e Bellman-Ford
Treinamento para Competições de Programacão - Single-Source Shortest Paths: Dijkstra e Bellman-Ford
Treinamento para Competições de Programacão - Single-Source Shortest Paths: Dijkstra e Bellman-Ford
Treinamento para Competições de Programacão - Single-Source Shortest Paths: Dijkstra e Bellman-Ford
Treinamento para Competições de Programacão - Single-Source Shortest Paths: Dijkstra e Bellman-Ford
Treinamento para Competições de Programacão - Single-Source Shortest Paths: Dijkstra e Bellman-Ford
Treinamento para Competições de Programacão - Single-Source Shortest Paths: Dijkstra e Bellman-Ford
Treinamento para Competições de Programacão - Single-Source Shortest Paths: Dijkstra e Bellman-Ford
Treinamento para Competições de Programacão - Single-Source Shortest Paths: Dijkstra e Bellman-Ford
Treinamento para Competições de Programacão - Single-Source Shortest Paths: Dijkstra e Bellman-Ford
Treinamento para Competições de Programacão - Single-Source Shortest Paths: Dijkstra e Bellman-Ford
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Treinamento para Competições de Programacão - Single-Source Shortest Paths: Dijkstra e Bellman-Ford

1,594

Published on

Aula sobre os algoritmos de Dijkstra e Bellman-Ford pra turma de Tópicos Avançados de Programação com código em C++.

Aula sobre os algoritmos de Dijkstra e Bellman-Ford pra turma de Tópicos Avançados de Programação com código em C++.

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
1,594
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
40
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. TREINAMENTO PARA COMPETIÇÕES DE PROGRAMAÇÃO GRAFOS - PARTE III SINGLE-SOURCE SHORTEST PATHS:DIJKSTRA E BELLMAN-FORD Murilo Adriano Vasconcelos http://murilo.wordpress.com
  • 2. O problema • Dado um grafo ponderado G(V, E), onde as arestas tem custos positivos, queremos saber qual o custo do menor caminho de um vértice origem u ∈ V para todos os outros vértices v ∈ V.
  • 3. O algoritmo de Dijkstraconst int MAXV = 1000; // número máximo de vérticesconst int INF = 0x3f3f3f3f; // cuidado com esse valorlist< pair<int, int> > grafo[MAXV]; // lista de adjacênciaint dist[MAXV]; // a resposta ficará neste vetorint visited[MAXV], N; // N é a quantidade de vértices atualvoid leitura(){ cin >> N >> m; // quantidade de vertices e arestas int de, para, custo; // limpa o grafo for (int i = 0; i < N; ++i) g[i].clear(); // leitura da entrada for (int i = 0; i < m; ++i) { cin >> de >> para >> custo; g[de].push_back(make_pair(para, custo)); }}
  • 4. O algoritmo de Dijkstravoid dijkstra(int origem){ for (int i = 0; i < N; ++i) { dist[i] = INF; visited[i] = false; } // nossa heap de máximo onde: first = custo, // second = vertice priority_queue< pair<int, int> > pq; pq.push(make_pair(0, origem)); dist[origem] = 0; // distancia da origem pra ela // mesma é 0 pair<int, int> atual; list< pair<int, int> >::iterator it;
  • 5. O algoritmo de Dijkstra while (!pq.empty()) { atual = pq.top(); pq.pop(); int custo = -atual.first; // nao esqueça do ‘-’! int v = atual.second; if (visited[v]) continue; // já processamos ele visited[v] = true; // se cheguei aqui, o menor custo // de origem para v já foi calculado // para cada aresta, tentamos fazer a relaxação for (it = g[v].begin(); it != g[v].end(); ++it) { if (dist[it->second] > w + it->first) { dist[it->second] = w + it->first; pq.push(make_pair(-dist[it->second], it->second)); } } }} // dijkstra
  • 6. O algoritmo de Dijkstra • Inicialmente, colocamos na heap, o vértice de origem com o custo 0 e dizemos que o custo da origem para origem é 0 • Em seguida, para cada elemento v com o menor custo (top() na priority_queue), tentamos relaxar (diminuindo) o custo dos seus vizinhos • Se o custo de algum vértice u for maior que o custo de v mais o custo da aresta que liga o v a u, diminuímos o custo de u para este valor
  • 7. Dijkstra - demonstração
  • 8. Dijkstra - análise • Complexidade O(|E| log |V|) • |V| = 1000, |E| = 100.000 < 10^6 operações (feasible) • Comparativo com Floyd-Warshall O(|V|^3) • |V| = 1000, 10^9 operações (geralmente unfeasible)
  • 9. Outro problema • Dado um grafo ponderado G(V, E), onde as arestas podem ter custos negativos, queremos saber qual o custo do menor caminho de um vértice origem u ∈ V para todos os outros vértices v ∈ V.
  • 10. Usar o Dijkstra? • Seja G, este grafo: 2 -1 -4 0 10 1 3 4 2 1
  • 11. Usar o Dijkstra? Seja G, este grafo: 2 -1 -4 0 10 1 3 4 2 1 Qual a menor distância entre 0 e 4?
  • 12. Usar o Dijkstra? Não podemos usar o Dijkstra, pois o grafo contém um ciclo negativo. 2 -1 -4 0 10 1 3 4 2 1 Podemos ficar infinitamente neste ciclo pois o custo sempre diminuirá
  • 13. O algoritmo Bellman-Ford • O algoritmo de Bellman-Ford encontra o menor caminho entre um vértice origem e todos os outros se o grafo não tiver ciclos negativos • Se o grafo tiver ciclos negativos, o algoritmo serve para detectá-los
  • 14. O algoritmo Bellman-Ford • Utiliza a representação de lista de arestas • Faz a relaxação utilizando a desigualdade triangular |V| - 1 vezes • Se após |V| - 1 relaxações, ainda conseguirmos diminuir o custo de algum vértice, o grafo contém ciclos negativos
  • 15. O algoritmo Bellman-Fordconst int MAXV = 1000; // número máximo de vérticesconst int INF = 0x3f3f3f3f; // cuidado com esse valorstruct aresta { int u, v, w; }; // de, para, custovector<aresta> grafo; // pode ser um array se // soubermos o máximo de arestasint custo[MAXV], N, E; // custo, vértices, arestasvoid le(){ cin >> N >> E; // le a quant. de vértices e arestas grafo.clear(); aresta ar; for (int i = 0; i < E; ++i) { cin >> ar.u >> ar.v >> ar.w; // de, para, custo grafo.push_back(ar); }}
  • 16. O algoritmo Bellman-Fordbool bellan_ford(int origem){ for (int i = 0; i < V; ++i) custo[i] = INF; custo[origem] = 0; for (int i = 0; i < V - 1; ++i) { // até V - 1 for (int j = 0; j < E; ++j) { int u = grafo[j].u; int v = grafo[j].v; int w = grafo[j].w; // relaxação if (custo[v] > custo[u] + w) { custo[v] = custo[u] + w; } } }
  • 17. O algoritmo Bellman-Ford // checagem de ciclos de custo negativo for (int j = 0; j < E; ++j) { int u = grafo[j].u; int v = grafo[j].v; int w = grafo[j].w; // se ainda é possível diminuir o custo // é porque sempre vai ter como (ciclo negativo) if (custo[v] > custo[u] + w) { return false; // ciclo encontrado } } return true; // nenhum ciclo negativo} // bellman_ford()
  • 18. Bellman-Ford - análise • Complexidade O(VE) • Loop de fora V vezes, loop interno E vezes
  • 19. Alguns ProblemasDijkstra (UVA): 341 - Non-Stop Travel 929 - Number Maze  1202 - Finding Nemo 10166 - Travel 10269 - Adventure of Super Mario 10278 - Fire Station 10389 - Subway 10603 - Fill 10801 - Lift Hopping 10986 - Sending email 11367 - Full Tank? 11377 - Airport Setup 11492 - Babel 11833 - Route Change 12138 - Chemical PlantBellman Ford (UVA):  558 - Wormholes  10557 - XYZZY  11280 - Flying to Fredericton
  • 20. Dúvidas?

×