Skip to content

Adding Graph Algorithms #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions Graphs/BFS Graph.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Program to print BFS traversal from a given
// source vertex. BFS(int s) traverses vertices
// reachable from s.
#include<iostream>
#include <list>

using namespace std;

// This class represents a directed graph using
// adjacency list representation
class Graph
{
int V; // No. of vertices

// Pointer to an array containing adjacency
// lists
list<int> *adj;
public:
Graph(int V); // Constructor

// function to add an edge to graph
void addEdge(int v, int w);

// prints BFS traversal from a given source s
void BFS(int s);
};

Graph::Graph(int V)
{
this->V = V;
adj = new list<int>[V];
}

void Graph::addEdge(int v, int w)
{
adj[v].push_back(w); // Add w to v�s list.
}

void Graph::BFS(int s)
{
// Mark all the vertices as not visited
bool *visited = new bool[V];
for(int i = 0; i < V; i++)
visited[i] = false;

// Create a queue for BFS
list<int> queue;

// Mark the current node as visited and enqueue it
visited[s] = true;
queue.push_back(s);

// 'i' will be used to get all adjacent
// vertices of a vertex
list<int>::iterator i;

while(!queue.empty())
{
// Dequeue a vertex from queue and print it
s = queue.front();
cout << s << " ";
queue.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 = adj[s].begin(); i != adj[s].end(); ++i)
{
if (!visited[*i])
{
visited[*i] = true;
queue.push_back(*i);
}
}
}
}

// Driver program to test methods of graph class
int main()
{
// Create a graph given in the above diagram
Graph g(4);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 2);
g.addEdge(2, 0);
g.addEdge(2, 3);
g.addEdge(3, 3);

cout << "Following is Breadth First Traversal "
<< "(starting from vertex 2) \n";
g.BFS(2);

return 0;
}

87 changes: 87 additions & 0 deletions Graphs/DFS Graph.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// C++ program to print DFS traversal from
// a given vertex in a given graph
#include<bits/stdc++.h>
using namespace std;

// Graph class represents a directed graph
// using adjacency list representation
class Graph
{
int V; // No. of vertices

// Pointer to an array containing
// adjacency lists
list<int> *adj;

// A recursive function used by DFS
void DFSUtil(int v, bool visited[]);
public:
Graph(int V); // Constructor

// function to add an edge to graph
void addEdge(int v, int w);

// DFS traversal of the vertices
// reachable from v
void DFS(int v);
};

Graph::Graph(int V)
{
this->V = V;
adj = new list<int>[V];
}

void Graph::addEdge(int v, int w)
{
adj[v].push_back(w); // Add w to v�s list.
}

void Graph::DFSUtil(int v, bool visited[])
{
// Mark the current node as visited and
// print it
visited[v] = true;
cout << v << " ";

// Recur for all the vertices adjacent
// to this vertex
list<int>::iterator i;
for (i = adj[v].begin(); i != adj[v].end(); ++i)
if (!visited[*i])
DFSUtil(*i, visited);
}

// DFS traversal of the vertices reachable from v.
// It uses recursive DFSUtil()
void Graph::DFS(int v)
{
// Mark all the vertices as not visited
bool *visited = new bool[V];
for (int i = 0; i < V; i++)
visited[i] = false;

// Call the recursive helper function
// to print DFS traversal
DFSUtil(v, visited);
}

// Driver code
int main()
{
// Create a graph given in the above diagram
Graph g(4);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 2);
g.addEdge(2, 0);
g.addEdge(2, 3);
g.addEdge(3, 3);

cout << "Following is Depth First Traversal"
" (starting from vertex 2) \n";
g.DFS(2);

return 0;
}

101 changes: 101 additions & 0 deletions Graphs/PrintHamiltonianPathInGraph.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#include <iostream>
#include <vector>
using namespace std;

// data structure to store graph edges
struct Edge {
int src, dest;
};

// class to represent a graph object
class Graph
{
public:
// An array of vectors to represent adjacency list
vector<int> *adjList;

// Constructor
Graph(vector<Edge> const &edges, int N)
{
// allocate memory
adjList = new vector<int>[N];

// add edges to the undirected graph
for (unsigned i = 0; i < edges.size(); i++)
{
int src = edges[i].src;
int dest = edges[i].dest;

adjList[src].push_back(dest);
adjList[dest].push_back(src);
}
}
};

void printAllHamiltonianPaths(Graph const& g, int v, vector<bool>
visited, vector<int> &path, int N)
{
// if all the vertices are visited, then
// Hamiltonian path exists
if (path.size() == N)
{
// print Hamiltonian path
for (int i : path)
cout << i << " ";
cout << endl;

return;
}

// Check if every edge starting from vertex v leads
// to a solution or not
for (int w : g.adjList[v])
{
// process only unvisited vertices as Hamiltonian
// path visits each vertex exactly once
if (!visited[w])
{
visited[w] = true;
path.push_back(w);

// check if adding vertex w to the path leads
// to solution or not
printAllHamiltonianPaths(g, w, visited, path, N);

// Backtrack
visited[w] = false;
path.pop_back();
}
}
}

// main function
int main()
{
// consider complete graph having 4 vertices
vector<Edge> edges =
{
{0, 1}, {0, 2}, {0, 3}, {1, 2}, {1, 3}, {2, 3}
};

// starting node
int start = 0;

// Number of vertices in the graph
int N = 4;

// create a graph from edges
Graph g(edges, N);

// add starting node to the path
vector<int> path;
path.push_back(start);

// mark start node as visited
vector<bool> visited(N);
visited[start] = true;

printAllHamiltonianPaths(g, start, visited, path, N);

return 0;
}
106 changes: 106 additions & 0 deletions Graphs/TwoCliqueProblem.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// C++ program to find out whether a given graph can be
// converted to two Cliques or not.
#include <bits/stdc++.h>
using namespace std;

const int V = 5;

// This function returns true if subgraph reachable from
// src is Bipartite or not.
bool isBipartiteUtil(int G[][V], int src, int colorArr[])
{
colorArr[src] = 1;

// Create a queue (FIFO) of vertex numbers and enqueue
// source vertex for BFS traversal
queue <int> q;
q.push(src);

// Run while there are vertices in queue (Similar to BFS)
while (!q.empty())
{
// Dequeue a vertex from queue
int u = q.front();
q.pop();

// Find all non-colored adjacent vertices
for (int v = 0; v < V; ++v)
{
// An edge from u to v exists and destination
// v is not colored
if (G[u][v] && colorArr[v] == -1)
{
// Assign alternate color to this adjacent
// v of u
colorArr[v] = 1 - colorArr[u];
q.push(v);
}

// An edge from u to v exists and destination
// v is colored with same color as u
else if (G[u][v] && colorArr[v] == colorArr[u])
return false;
}
}

// If we reach here, then all adjacent vertices can
// be colored with alternate color
return true;
}

// Returns true if a Graph G[][] is Bipartite or not. Note
// that G may not be connected.
bool isBipartite(int G[][V])
{
// Create a color array to store colors assigned
// to all veritces. Vertex number is used as index in
// this array. The value '-1' of colorArr[i]
// is used to indicate that no color is assigned to
// vertex 'i'. The value 1 is used to indicate first
// color is assigned and value 0 indicates
// second color is assigned.
int colorArr[V];
for (int i = 0; i < V; ++i)
colorArr[i] = -1;

// One by one check all not yet colored vertices.
for (int i = 0; i < V; i++)
if (colorArr[i] == -1)
if (isBipartiteUtil(G, i, colorArr) == false)
return false;

return true;
}

// Returns true if G can be divided into
// two Cliques, else false.
bool canBeDividedinTwoCliques(int G[][V])
{
// Find complement of G[][]
// All values are complemented except
// diagonal ones
int GC[V][V];
for (int i=0; i<V; i++)
for (int j=0; j<V; j++)
GC[i][j] = (i != j)? !G[i][j] : 0;

// Return true if complement is Bipartite
// else false.
return isBipartite(GC);
}

// Driver program to test above function
int main()
{
int G[][V] = {{0, 1, 1, 1, 0},
{1, 0, 1, 0, 0},
{1, 1, 0, 0, 0},
{0, 1, 0, 0, 1},
{0, 0, 0, 1, 0}
};

canBeDividedinTwoCliques(G) ? cout << "Yes" :
cout << "No";
return 0;
}