Skip to content
Snippets Groups Projects
Commit 4aae2173 authored by Filip Štěpánek's avatar Filip Štěpánek
Browse files

Progress

parent 9d0e003b
No related branches found
No related tags found
No related merge requests found
......@@ -2,25 +2,47 @@
#include <vector>
#include <list>
#include <stack>
#include <bits/stdc++.h>
struct Node{
struct Node {
int index;
std::list<int> neighbors;
std::list<Node *> neighbors;
std::list<Node *> directNeighbors;
int distance = INT_MAX;
bool visited = false;
Node* predecesor;
};
struct Cluster {
std::vector<Node *> nodes;
bool visited = false;
int distance = INT_MAX;
Node* nearestFactory;
};
class MyCompare {
public:
bool operator()(Node *a, Node *b) {
return (a->distance) > (b->distance);
}
};
typedef std::vector<Node> uGraph;
void Kosarajus();
uGraph getTranspose(uGraph originalGraph);
void transpose();
void fillOrder(Node *v, std::stack<Node *> &Stack);
void fillOrder(int v, bool visited[],
std::stack<int> &Stack);
void DFSUtil(Node *v, Cluster *pCluster);
void DFSUtil(int v, bool visited[]);
void BFS(Node *src);
uGraph graph;
uGraph originalGraph;
std::vector<Cluster> clusters;
int factoryCount, conveyorsCount, centralStore;
int main() {
......@@ -34,69 +56,81 @@ int main() {
int source, dest;
for (int i = 0; i < conveyorsCount; ++i) {
std::scanf("%d %d", &source, &dest);
graph[source].neighbors.push_back(dest);
graph[source].neighbors.push_back(&graph[dest]);
graph[source].directNeighbors.push_back(&graph[dest]);
graph[dest].directNeighbors.push_back(&graph[source]);
}
originalGraph = graph;
BFS(&graph[centralStore]);
Kosarajus();
sort(clusters.begin(), clusters.end(), [](const Cluster & a, const Cluster & b) -> bool {
return a.distance > b.distance;
});
return 0;
}
void Kosarajus() {
std::stack<int> stack;
for (int i = 0; i < graph.size(); i++)
graph[i].visited = false;
// Mark all the vertices as
// not visited (For first DFS)
bool *visited = new bool[factoryCount];
std::fill_n(visited, factoryCount, false);
std::stack<Node *> stack;
// Fill vertices in stack according
// to their finishing times
for (int i = 0; i < factoryCount; i++)
if (visited[i] == false)
fillOrder(i, visited, stack);
for (int i = 0; i < graph.size(); ++i)
if (!graph[i].visited)
fillOrder(&graph[i], stack);
// Create a reversed graph
graph = getTranspose(graph);
transpose();
// Mark all the vertices as not
// visited (For second DFS)
std::fill_n(visited, factoryCount, false);
for (auto i = graph.begin(); i != graph.end(); i++)
i->visited = false;
// Now process all vertices in
// order defined by stack
while (stack.empty() == false) {
// Pop a vertex from stack
int v = stack.top();
Node *v = stack.top();
stack.pop();
// Print SCC of the popped vertex
if (visited[v] == false) {
DFSUtil(v, visited);
if (!v->visited) {
Cluster cluster{};
DFSUtil(v, &cluster);
std::cout << std::endl;
clusters.push_back(cluster);
}
}
std::cout << "finish" << std::endl;
}
// Function that fills stack with vertices
// in increasing order of finishing times
void fillOrder(int v, bool visited[], std::stack<int> &Stack) {
void fillOrder(Node *v, std::stack<Node *> &Stack) {
// Mark the current node as
// visited and print it
visited[v] = true;
v->visited = true;
// Recur for all the vertices
// adjacent to this vertex
std::list<int>::iterator i;
for (i = graph[v].neighbors.begin();
i != graph[v].neighbors.end(); ++i) {
std::list<Node *>::iterator i;
for (i = v->neighbors.begin(); i != v->neighbors.end(); ++i) {
// If child node *i is unvisited
if (!visited[*i]) {
fillOrder(*i, visited, Stack);
if (!(*i)->visited) {
fillOrder(*i, Stack);
}
}
......@@ -107,38 +141,87 @@ void fillOrder(int v, bool visited[], std::stack<int> &Stack) {
// Recursive function to print DFS
// starting from v
void DFSUtil(int v, bool visited[]) {
void DFSUtil(Node *v, Cluster *pCluster) {
// Mark the current node as
// visited and print it
visited[v] = true;
std::cout << v << " ";
v->visited = true;
std::cout << v->index << " ";
pCluster->nodes.push_back(v);
if (pCluster->distance > v->distance) {
pCluster->distance = v->distance;
pCluster->nearestFactory = v;
}
// Recur for all the vertices
// adjacent to this vertex
std::list<int>::iterator i;
std::list<Node *>::iterator it;
// Traverse Adjacency List of node v
for (i = graph[v].neighbors.begin(); i != graph[v].neighbors.end(); ++i) {
for (it = v->neighbors.begin(); it != v->neighbors.end(); ++it) {
// If child node *i is unvisited
if (!visited[*i])
DFSUtil(*i, visited);
if (!(*it)->visited)
DFSUtil((*it), pCluster);
}
}
// Function to get the transpose of
// the given graph
uGraph getTranspose(uGraph originalGraph) {
uGraph transposedGraph(originalGraph.size());
void transpose() {
uGraph transposedGraph = graph;
//To be safe make copy
for (int j = 0; j < transposedGraph.size(); ++j)
transposedGraph[j].neighbors.clear();
for (int v = 0; v < originalGraph.size(); v++) {
// Recur for all the vertices
// adjacent to this vertex
std::list<int>::iterator i;
for (i = graph[v].neighbors.begin(); i != graph[v].neighbors.end(); ++i) {
for (std::list<Node *>::iterator i = graph[v].neighbors.begin(); i != graph[v].neighbors.end(); ++i) {
// Add to adjacency list
transposedGraph[*i].neighbors.push_back(v);
transposedGraph[(*i)->index].neighbors.push_back(&graph[v]);
}
}
// Return the reversed graph
return transposedGraph;
graph = transposedGraph;
}
void BFS(Node *src) {
for (int i = 0; i < graph.size(); i++)
graph[i].visited = false;
// Create a queue for BFS
std::list<Node *> queue;
std::list<int> levelQueue;
// Mark the current node as visited and enqueue it
src->visited = true;
queue.push_back(src);
levelQueue.push_back(0);
// 'i' will be used to get all adjacent
// vertices of a vertex
std::list<Node *>::iterator i;
int level = 1;
while (!queue.empty()) {
// Dequeue a vertex from queue and print it
src = queue.front();
src->distance = levelQueue.front();
std::cout << src->index << "-" << src->distance << std::endl;
queue.pop_front();
levelQueue.pop_front();
// Get all adjacent vertices of the dequeued
// vertex s. If a adjacent has not been visited,
// then mark it visited and enqueue it
for (i = src->directNeighbors.begin(); i != src->directNeighbors.end(); ++i) {
if (!(*i)->visited) {
(*i)->visited = true;
(*i)->predecesor = src;
queue.push_back(*i);
levelQueue.push_back(level);
}
}
level++;
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment