Skip to content

Instantly share code, notes, and snippets.

@marcoscastro
Last active April 17, 2024 17:30
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marcoscastro/d4e0df5b134c2cd63cf2 to your computer and use it in GitHub Desktop.
Save marcoscastro/d4e0df5b134c2cd63cf2 to your computer and use it in GitHub Desktop.
Programação em C++ - Algoritmo de Dijkstra
// Implementação do algoritmo de Dijkstra
// Teste: http://br.spoj.com/problems/ENGARRAF/
#include <iostream>
#include <list>
#include <queue>
#define INFINITO 10000000
using namespace std;
class Grafo
{
private:
int V; // número de vértices
// ponteiro para um array contendo as listas de adjacências
list<pair<int, int> > * adj;
public:
// construtor
Grafo(int V)
{
this->V = V; // atribui o número de vértices
/*
cria as listas onde cada lista é uma lista de pairs
onde cada pair é formado pelo vértice destino e o custo
*/
adj = new list<pair<int, int> >[V];
}
// adiciona uma aresta ao grafo de v1 à v2
void addAresta(int v1, int v2, int custo)
{
adj[v1].push_back(make_pair(v2, custo));
}
// algoritmo de Dijkstra
int dijkstra(int orig, int dest)
{
// vetor de distâncias
int dist[V];
/*
vetor de visitados serve para caso o vértice já tenha sido
expandido (visitado), não expandir mais
*/
int visitados[V];
// fila de prioridades de pair (distancia, vértice)
priority_queue < pair<int, int>,
vector<pair<int, int> >, greater<pair<int, int> > > pq;
// inicia o vetor de distâncias e visitados
for(int i = 0; i < V; i++)
{
dist[i] = INFINITO;
visitados[i] = false;
}
// a distância de orig para orig é 0
dist[orig] = 0;
// insere na fila
pq.push(make_pair(dist[orig], orig));
// loop do algoritmo
while(!pq.empty())
{
pair<int, int> p = pq.top(); // extrai o pair do topo
int u = p.second; // obtém o vértice do pair
pq.pop(); // remove da fila
// verifica se o vértice não foi expandido
if(visitados[u] == false)
{
// marca como visitado
visitados[u] = true;
list<pair<int, int> >::iterator it;
// percorre os vértices "v" adjacentes de "u"
for(it = adj[u].begin(); it != adj[u].end(); it++)
{
// obtém o vértice adjacente e o custo da aresta
int v = it->first;
int custo_aresta = it->second;
// relaxamento (u, v)
if(dist[v] > (dist[u] + custo_aresta))
{
// atualiza a distância de "v" e insere na fila
dist[v] = dist[u] + custo_aresta;
pq.push(make_pair(dist[v], v));
}
}
}
}
// retorna a distância mínima até o destino
return dist[dest];
}
};
int main(int argc, char *argv[])
{
Grafo g(5);
g.addAresta(0, 1, 4);
g.addAresta(0, 2, 2);
g.addAresta(0, 3, 5);
g.addAresta(1, 4, 1);
g.addAresta(2, 1, 1);
g.addAresta(2, 3, 2);
g.addAresta(2, 4, 1);
g.addAresta(3, 4, 1);
cout << g.dijkstra(0, 4) << endl;
return 0;
}
@sugayaa
Copy link

sugayaa commented Sep 6, 2019

Olá amigo tudo bem? Queria saber se há alguma modificação que possa ser feita que ao contrário de retornar a distância percorrida, retornar os vértices pertencentes ao caminho mínimo. Abraços!

Acredito que você teria de guardar o antecessor de cada vértice, pode guardar em um vetor por exemplo. Feito isso, a partir do destino ir imprindo o antecessor até chegar no vértice inicial.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment