Created
October 10, 2015 22:46
-
-
Save goldsborough/5238616e15154af76c0e to your computer and use it in GitHub Desktop.
Are two vertices in a directed graph connected?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class DirectedGraph | |
{ | |
public: | |
using size_t = std::size_t; | |
using vertex_t = std::size_t; | |
using adjacent_t = std::vector<vertex_t>; | |
DirectedGraph(size_t vertices) | |
: _edges(0) | |
, _vertices(vertices) | |
{ } | |
void add_vertex() | |
{ | |
_vertices.push_back({}); | |
} | |
void add_edge(vertex_t from, vertex_t to) | |
{ | |
_assert_vertex_in_range(from); | |
_assert_vertex_in_range(to); | |
_vertices[from].outgoing.push_back(to); | |
_vertices[to].incoming.push_back(from); | |
++_edges; | |
} | |
void add_route(const std::vector<vertex_t>& route) | |
{ | |
for (auto j = route.begin(), i = j++, end = route.end(); | |
j != end; | |
++i, ++j) | |
{ | |
add_edge(*i, *j); | |
} | |
} | |
adjacent_t incoming(vertex_t vertex) const | |
{ | |
_assert_vertex_in_range(vertex); | |
return _vertices[vertex].incoming; | |
} | |
adjacent_t outgoing(vertex_t vertex) const | |
{ | |
_assert_vertex_in_range(vertex); | |
return _vertices[vertex].outgoing; | |
} | |
size_t vertex_number() const | |
{ | |
return _vertices.size(); | |
} | |
size_t edge_number() const | |
{ | |
return _edges; | |
} | |
bool is_empty() const | |
{ | |
return _vertices.empty(); | |
} | |
private: | |
struct Vertex { adjacent_t incoming, outgoing; }; | |
void _assert_vertex_in_range(vertex_t vertex) const | |
{ | |
if (vertex >= _vertices.size()) | |
{ | |
throw std::invalid_argument("Vertex out of range!"); | |
} | |
} | |
size_t _edges; | |
std::vector<Vertex> _vertices; | |
}; | |
class Is_Connected | |
{ | |
public: | |
using vertex_t = DirectedGraph::vertex_t; | |
bool operator()(const DirectedGraph& graph, | |
vertex_t vertex, | |
vertex_t target) | |
{ | |
bitset_t visited(graph.vertex_number(), false); | |
return _is_connected(graph, vertex, target, visited); | |
} | |
private: | |
using bitset_t = std::vector<bool>; | |
bool _is_connected(const DirectedGraph& graph, | |
vertex_t vertex, | |
vertex_t target, | |
bitset_t& visited) const | |
{ | |
if (visited[vertex]) return false; | |
if (vertex == target) return true; | |
visited[vertex] = true; | |
for (const auto& adjacent : graph.outgoing(vertex)) | |
{ | |
if (_is_connected(graph, adjacent, target, visited)) | |
{ | |
return true; | |
} | |
} | |
return false; | |
} | |
}; | |
bool is_connected(const DirectedGraph& graph, | |
DirectedGraph::vertex_t vertex, | |
DirectedGraph::vertex_t target) | |
{ | |
Is_Connected check; | |
return check(graph, vertex, target); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment