-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathBellman Ford.cpp
More file actions
80 lines (65 loc) · 2.07 KB
/
Bellman Ford.cpp
File metadata and controls
80 lines (65 loc) · 2.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// Bellman-Ford
//
// Encontra o menor caminho de um ponto a outro de um grafo
// que pode conter arestas negativas.
// V - Número de vértices
// E - Número de arestas
// O(V*E)
#define INF 0x3f3f3f3f
struct Edge {
int src, dest, weight;
};
int V, E;
vector<Edge> edges(E);
vector<int> dist(V, INF);
int bellmanFord(int src, int dest) {
dist[src] = 0;
vector<int> prnt(V, -1);
// Relaxa os vértices |V-1| vezes para garantir a menor distância.
for (int i = 0; i < V - 1; i++) {
for (const auto& [u, v, wei] : edges) {
if (dist[u] != INF && dist[u] + wei < dist[v]) {
dist[v] = dist[u] + wei;
prnt[v] = u;
}
}
}
return dist[dest];
}
// Vê se existe um ciclo no grafo.
// Retorna um vetor vazio se não houver ciclo negativo
// ou um vetor com os vértices do ciclo caso exista
vector<int> findNegativeCycle() {
vector<int> prnt(V, -1); // Para rastrear o predecessor de cada vértice
dist[0] = 0; // Pode começar de qualquer ponto (nesse caso 0).
for (int i = 0; i < V - 1; i++) {
for (const auto& [u, v, wei] : edges) {
if (dist[u] != INF && dist[u] + wei < dist[v]) {
dist[v] = dist[u] + wei;
prnt[v] = u;
}
}
}
// Depois de relaxar |V-1| vezes, tentar relaxar mais
// uma vez para encontrar o ciclo.
int cycleVertex = -1;
for (const auto& [u, v, wei] : edges) {
if (dist[u] != INF && dist[u] + wei < dist[v]) {
cycleVertex = v;
break;
}
}
if (cycleVertex == -1)
return {-1}; // Não há ciclo negativo
// Para garantir que chegamos em um vértice do ciclo, andamos V passos
for (int i = 0; i < V; i++)
cycleVertex = prnt[cycleVertex];
vector<int> cycle;
for (int u = cycleVertex;; u = prnt[u]) {
cycle.push_back(u);
if (u == cycleVertex && cycle.size() > 1)
break;
}
reverse(cycle.begin(), cycle.end());
return cycle;
}