Kosaraju added
This commit is contained in:
commit
56a5b594e4
4 changed files with 171 additions and 0 deletions
6
Kosaraju/CMakeLists.txt
Normal file
6
Kosaraju/CMakeLists.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
cmake_minimum_required(VERSION 3.10)
|
||||
project(Kosaraju)
|
||||
add_executable(Kosaraju
|
||||
digraph.cpp
|
||||
digraph.h
|
||||
main.cpp)
|
49
Kosaraju/digraph.cpp
Normal file
49
Kosaraju/digraph.cpp
Normal file
|
@ -0,0 +1,49 @@
|
|||
#include "digraph.h"
|
||||
|
||||
Node::Node(std::list<int> neighbours_) : neighbours(std::move(neighbours_))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Node::add_edge(int v)
|
||||
{
|
||||
neighbours.push_back(v);
|
||||
}
|
||||
|
||||
Digraph::Digraph(size_t num_nodes) : nodes(num_nodes)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Digraph::add_edge(int from, int to)
|
||||
{
|
||||
nodes[from].add_edge(to);
|
||||
}
|
||||
|
||||
std::list<int> Digraph::adjList(int node_id) const
|
||||
{
|
||||
return (nodes[node_id]).neighbours;
|
||||
}
|
||||
|
||||
bool Digraph::isEdge(int from, int to) const
|
||||
{
|
||||
return (std::find(adjList(from).begin(), adjList(from).end(), to) != adjList(from).end());
|
||||
}
|
||||
|
||||
size_t Digraph::num_nodes() const
|
||||
{
|
||||
return nodes.size();
|
||||
}
|
||||
|
||||
Digraph Digraph::transpose() const
|
||||
{
|
||||
Digraph G(num_nodes());
|
||||
for (int i = 0; i < num_nodes(); i++)
|
||||
{
|
||||
for (auto const& j: ((nodes[i]).neighbours))
|
||||
{
|
||||
G.add_edge(j,i);
|
||||
}
|
||||
}
|
||||
return G;
|
||||
}
|
32
Kosaraju/digraph.h
Normal file
32
Kosaraju/digraph.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
#ifndef C___DIGRAPH_H
|
||||
#define C___DIGRAPH_H
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
struct Node {
|
||||
std::list<int> neighbours;
|
||||
|
||||
Node() = default;
|
||||
Node(std::list<int> neighbours);
|
||||
void add_edge(int v);
|
||||
};
|
||||
|
||||
class Digraph {
|
||||
public:
|
||||
Digraph(size_t num_nodes);
|
||||
void add_edge(int from, int to);
|
||||
std::list<int> adjList(int node_id) const;
|
||||
size_t num_nodes() const;
|
||||
Digraph transpose() const;
|
||||
bool isEdge(int from, int to) const;
|
||||
|
||||
private:
|
||||
std::vector<Node> nodes;
|
||||
};
|
||||
|
||||
#endif //C___DIGRAPH_H
|
||||
|
||||
|
84
Kosaraju/main.cpp
Normal file
84
Kosaraju/main.cpp
Normal file
|
@ -0,0 +1,84 @@
|
|||
// Kosaraju’s algorithm to find strongly connected components of a directed graph
|
||||
// Authors: Georǵi Kocharyan, Maximilian Keßler
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
#include <stack>
|
||||
|
||||
#include "digraph.h"
|
||||
|
||||
// push nodes in post-order
|
||||
void dfs1(Digraph const & G, int n, std::vector<bool> & vis, std::stack<int> & node_order) {
|
||||
if (vis[n])
|
||||
{
|
||||
return; //if node is already visited don't
|
||||
}
|
||||
|
||||
vis[n] = true;
|
||||
|
||||
for(auto i: G.adjList(n))
|
||||
{
|
||||
dfs1(G, i, vis, node_order);
|
||||
}
|
||||
|
||||
node_order.push(n);
|
||||
}
|
||||
|
||||
//this function traverses the transpose graph
|
||||
void dfs2(Digraph const & G, int n, std::vector<bool> & vis2, std::stack<int> & node_order){
|
||||
if (vis2[n])
|
||||
{
|
||||
return; // if node is already visited
|
||||
}
|
||||
|
||||
std::cout << n << " ";
|
||||
vis2[n] = true;
|
||||
|
||||
for(auto i: G.adjList(n))
|
||||
{
|
||||
dfs2(G, i, vis2, node_order);
|
||||
}
|
||||
}
|
||||
|
||||
// print each component in seperate line, output amount
|
||||
int kosaraju(Digraph const & G) {
|
||||
int scc_count = 0; //keep count of strongly connected components
|
||||
std::stack<int> node_order;
|
||||
std::vector<bool> vis2 (G.num_nodes(), false);
|
||||
std::vector<bool> vis (G.num_nodes(), false); //store node visit stat for dfs
|
||||
for(int i = 0; i < G.num_nodes(); i++)
|
||||
{
|
||||
dfs1(G, i, vis, node_order);
|
||||
}
|
||||
while(!node_order.empty()) {
|
||||
int node_id = node_order.top();
|
||||
node_order.pop();
|
||||
if (vis2[node_id] == false)
|
||||
{
|
||||
dfs2(G.transpose(), node_id, vis2, node_order);
|
||||
scc_count++;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
return scc_count;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int size = 10;
|
||||
Digraph G(size);
|
||||
G.add_edge(3,4);
|
||||
G.add_edge(4,3);
|
||||
G.add_edge(5,6);
|
||||
G.add_edge(6,7);
|
||||
G.add_edge(7,5);
|
||||
G.add_edge(7,3);
|
||||
G.add_edge(0,3);
|
||||
G.add_edge(3,0);
|
||||
|
||||
int components= kosaraju(G);
|
||||
std::cout<< "Components: "<< components << std::endl;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue