Skip to content

Instantly share code, notes, and snippets.

@TheRayTracer
Last active December 11, 2015 01:19
Show Gist options
  • Save TheRayTracer/4522782 to your computer and use it in GitHub Desktop.
Save TheRayTracer/4522782 to your computer and use it in GitHub Desktop.
A working implementation of the Bellman - Ford algorithm in C++. It will also detect and bail out if a negative cycle is detected.
#include <iostream>
#include <fstream>
#include <vector>
#include <cassert>
#include <limits>
#include <iomanip>
namespace std { }
using namespace std;
struct edge
{
size_t u, v;
long weight;
};
istream& operator>>(istream& is, edge& i)
{
return is >> i.u >> i.v >> i.weight;
}
long bellman_ford(const vector<edge>& store, const size_t s, const size_t nodes, const long max_weight, bool& negative_cycle_detected)
{
assert(s < nodes);
negative_cycle_detected = false;
vector<long> distance;
distance.resize(nodes);
for (size_t i = 0; i < distance.size(); distance[i] = max_weight, ++i);
distance[s] = 0;
long result_min = 0;
for (size_t i = 0; i < (distance.size() - 1); ++i)
{
for (size_t j = 0; j < store.size(); ++j)
{
if ((distance[store[j].u] + store[j].weight) < distance[store[j].v])
{
distance[store[j].v] = distance[store[j].u] + store[j].weight;
result_min = min(distance[store[j].v], result_min);
}
}
}
for (size_t i = 0; i < store.size(); ++i)
{
if ((distance[store[i].u] + store[i].weight) < distance[store[i].v])
{
negative_cycle_detected = true;
break;
}
}
return result_min;
}
int main(int argc, char* argv[])
{
vector<edge> store;
size_t nodes = 0, edges = 0;
long max_weight = LONG_MIN;
if (argc > 1)
{
ifstream ifs;
ifs.open(argv[1]);
ifs >> nodes >> edges;
edge e = {0};
while (ifs >> e)
{
--e.u;
--e.v;
store.push_back(e);
max_weight = max(max_weight, e.weight + 1);
}
ifs.close();
}
cout << "Input size: " << store.size() << endl;
assert(store.size() == edges);
long min_weight = max_weight;
bool abort = false;
for (size_t i = 0; i < nodes; ++i)
{
bool negative_cycle_detected = false;
long weight = bellman_ford(store, i, nodes, max_weight, negative_cycle_detected);
if (negative_cycle_detected == false)
{
cout << "Source: " << setw(4) << i << ", Weight: " << setw(4) << weight << endl;
min_weight = min(min_weight, weight);
}
else
{
cout << "Source: " << setw(4) << i << ", Negative Cycle Detected. No result. Aborting." << endl;
abort = true;
break;
}
}
if (abort == false)
{
cout << "Shortest shortest weight: " << setw(4) << min_weight << endl;
}
cin.get();
return 0;
}
6 7
1 2 -2
2 3 -1
3 1 4
3 4 2
3 5 -3
6 4 1
6 5 -4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment