Checking for bipartite-ness in a large graph, made up of several disconnected graphs? - data-structures

I was doing a problem on SPOJ SPOJ:BUGLIFE
It required me to check whether the graph was bipartite or not. I know the method for a single connected graph, but for a combination of disconnected graphs, my method gives Time limit exceeded error.
Here's my approach - Breadth First Search, using Circular Queues with the graph implemented by adjacency lists.
method -> Choose a source, and if that source vertex=unvisited, then start a Breadth First Search assuming it to be the source. If I found a conflict in the BFS, then I abort the whole thing. Else I move to another un-visited source.
How can I make this faster? or better?
P.S. I am new to Graph Theory, so please explain in detail.

The following implementation (C++ version) is fast enough when testing in very large dataset (edages>1000). Hope it helps.
struct NODE
{
int color;
vector<int> neigh_list;
};
bool checkAllNodesVisited(NODE *graph, int numNodes, int & index);
bool checkBigraph(NODE * graph, int numNodes)
{
int start = 0;
do
{
queue<int> Myqueue;
Myqueue.push(start);
graph[start].color = 0;
while(!Myqueue.empty())
{
int gid = Myqueue.front();
for(int i=0; i<graph[gid].neigh_list.size(); i++)
{
int neighid = graph[gid].neigh_list[i];
if(graph[neighid].color == -1)
{
graph[neighid].color = (graph[gid].color+1)%2; // assign to another group
Myqueue.push(neighid);
}
else
{
if(graph[neighid].color == graph[gid].color) // touble pair in the same group
return false;
}
}
Myqueue.pop();
}
} while (!checkAllNodesVisited(graph, numNodes, start)); // make sure all nodes visited
// to be able to handle several separated graphs, IMPORTANT!!!
return true;
}
bool checkAllNodesVisited(NODE *graph, int numNodes, int & index)
{
for (int i=0; i<numNodes; i++)
{
if (graph[i].color == -1)
{
index = i;
return false;
}
}
return true;
}

Related

Finding all bridge edges in an undirected graph? (Code not working)

I am learning about bridges in graphs.
I have the following C# code (also available in a fiddle - https://dotnetfiddle.net/XQEEdy):
using System;
using System.Collections.Generic;
public class Program
{
public class Graph
{
private int[,] adjMatrix;
public Graph(int vertices)
{
adjMatrix = new int[vertices, vertices];
}
public int[,] AdjMatrix
{
get
{
return adjMatrix;
}
}
public void AddEdge(int source, int destination)
{
adjMatrix[source, destination] = 1;
adjMatrix[destination, source] = 1;
}
}
public static HashSet<Tuple<int, int>> Bridges(Graph graph)
{
var visited = new HashSet<int>();
var bridges = new HashSet<Tuple<int, int>>();
var ids = new Dictionary<int, int>();
var lowLinkValues = new Dictionary<int, int>();
var parent = -1;
var id = 0;
for (int i = 0; i < graph.AdjMatrix.GetLength(0); i++)
{
if (visited.Contains(i))
{
continue;
}
Dfs(i, parent, id, bridges, ids, lowLinkValues, visited, graph.AdjMatrix);
}
return bridges;
}
private static void Dfs(
int vertex,
int parent,
int id,
HashSet<Tuple<int, int>> bridges,
Dictionary<int, int> ids,
Dictionary<int, int> lowLinkValues,
HashSet<int> visited,
int[,] adjMatrix)
{
visited.Add(vertex);
ids.Add(vertex, id);
lowLinkValues.Add(vertex, id);
id++;
for (int i = 0; i < adjMatrix.GetLength(0); i++)
{
if (parent == i)
{
continue;
}
if (!visited.Contains(i))
{
parent = vertex;
Dfs(i, parent, id, bridges, ids, lowLinkValues, visited, adjMatrix);
if (ids[vertex] < lowLinkValues[i])
{
bridges.Add(Tuple.Create(vertex, i));
}
else
{
lowLinkValues[vertex] = Math.Min(lowLinkValues[vertex], lowLinkValues[i]);
}
}
else
{
lowLinkValues[vertex] = Math.Min(lowLinkValues[vertex], ids[i]);
}
}
}
public static void Main()
{
// Adjacency Matrix:
var g = new Graph(11);
g.AddEdge(0, 1);
g.AddEdge(0, 2);
g.AddEdge(0, 3);
g.AddEdge(0, 4);
g.AddEdge(4, 2);
g.AddEdge(3, 5);
g.AddEdge(4, 6);
g.AddEdge(6, 3);
g.AddEdge(6, 7);
g.AddEdge(6, 8);
g.AddEdge(7, 9);
g.AddEdge(9, 10);
g.AddEdge(8, 10);
// bridges should be: 0--1, 3--5
// but bridges collection is empty
var bridges = Bridges(g);
foreach (var bridge in bridges)
{
Console.WriteLine(bridge.Item1);
Console.WriteLine(bridge.Item2);
Console.WriteLine("\n");
}
}
}
I have compared the code to: https://github.com/williamfiset/Algorithms/blob/master/src/main/java/com/williamfiset/algorithms/graphtheory/BridgesAdjacencyList.java
I do not see any real differences, but I am still getting nothing returned. Drawing the graph out, it looks like edge(0,1) and edge(3,5) should be bridges - as removing the edges would mean 1 & 5 would be disconnected from the graph.
Similarly, if I use the same test case from the github link I also get no bridges returned.
I am clearly missing something, but I've not been able to pick up what it might be. Does anyone see what the issue with my code is?
The problem appears to be that you've not implemented an actual depth-first search, though that appears to be your intention with the name Dfs. A depth-first search starts at some vertex and follows all edges from that vertex in a depth-first manner (follows all edges from the first child before looking at the next child).
Your algorithm, however, looks at every node and simply defines the parent as the current node, so it's not really searching, it's just looking at every node in numerical order. A simplified version of your code (in pseudocode):
Dfs(Vertex current):
mark current as visited
for each Vertex v in the graph:
if v is not visited:
Dfs(v)
Note there's no relationship between the vertex called "current" and the vertices examined from the graph. Instead, the algorithm should be more like this:
Dfs(Vertex current, Vertex parent):
mark current as visited
for each Vertex v in the graph:
if v is not visited:
if v shares an edge with current:
Dfs(v)
I'll leave it as an exercise for you to figure out how to patch your algorithm to fix this issue. There may be other issues as well. I stopped once I found the first issue.

Path exists between cities or not

The link to the problem is Q4 Traveling is Fun.
I can only think of a brute force approach to compute every possible gcd and run bfs from source to destination to check if there exists a path or not.
But the above approach gives TLE in 5 test cases.
Can anyone provide a more efficient approach ?
This is a quick implementation of the graph structure I would use:
class GCDGraph {
private Map<Integer, Set<Integer>> adj = new HashMap<>();
public GCDGraph(int g, int[] srcCities, int[] dstCities){
int n = srcCities.length;
for(int i=0;i<n;i++){
adj.put(i, new HashSet<>());
}
for(int i=0;i<n;i++){
for(int j=0;j<i;j++){
int gtmp = gcd(srcCities[i], dstCities[j]);
if(gtmp > g){
adj.get(i).add(j);
adj.get(j).add(i);
}
}
// we could add the connection i -> i (assuming srcCities[i] > g)
// but that would not help us find a path, as it introduces a cycle
}
}
private int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
public Set<Integer> adjacentVertices(int vertex){ return adj.get(vertex); }
public int size(){ return adj.size(); }
public boolean isEmpty(){ return size() == 0; }
public boolean hasPath(int src, int dst){
return buildPath(src, dst, new HashSet<>());
}
private boolean buildPath(int src, int dst, Set<Integer> tmp){
if(src == dst){
return true;
} else {
for(int nextVertex : adjacentVertices(src)){
if(tmp.contains(nextVertex))
continue;
tmp.add(nextVertex);
if(buildPath(nextVertex, dst, tmp))
return true;
tmp.remove(nextVertex);
}
}
return false;
}
}
It explicitly stores the adjacency as a Map (allowing fast lookup).
It has some utility methods (size, isEmpty).
It only looks up the GCD when it is being built, and only once for each x/y pair.
And it uses recursion to perform BFS, quitting as soon as possible.

Convert Recursive algorithm to Iterative

I am trying to implement following algorithm to a iterative one but I am not able to do it properly. Can some one please help me with this. Its a bipartite matching algorithm and I am having trouble in converting the bpm function to iterative one.
// A DFS based recursive function that returns true if a
// matching for vertex u is possible
bool bpm(bool bpGraph[M][N], int u, bool seen[], int matchR[])
{
// Try every job one by one
for (int v = 0; v < N; v++)
{
// If applicant u is interested in job v and v is
// not visited
if (bpGraph[u][v] && !seen[v])
{
seen[v] = true; // Mark v as visited
// If job 'v' is not assigned to an applicant OR
// previously assigned applicant for job v (which is matchR[v])
// has an alternate job available.
// Since v is marked as visited in the above line, matchR[v]
// in the following recursive call will not get job 'v' again
if (matchR[v] < 0 || bpm(bpGraph, matchR[v], seen, matchR))
{
matchR[v] = u;
return true;
}
}
}
return false;
}
// Returns maximum number of matching from M to N
int maxBPM(bool bpGraph[M][N])
{
// An array to keep track of the applicants assigned to
// jobs. The value of matchR[i] is the applicant number
// assigned to job i, the value -1 indicates nobody is
// assigned.
int matchR[N];
// Initially all jobs are available
memset(matchR, -1, sizeof(matchR));
int result = 0; // Count of jobs assigned to applicants
for (int u = 0; u < M; u++)
{
// Mark all jobs as not seen for next applicant.
bool seen[N];
memset(seen, 0, sizeof(seen));
// Find if the applicant 'u' can get a job
if (bpm(bpGraph, u, seen, matchR))
result++;
}
return result;
}
The trick is that you need a stack of actions. So when you enter the loop you first add to the stack all of the things you will do after what WOULD have been your recursive call, and THEN put the recursive call in. They will execute in the opposite order, and when you're doing the second half, you know what happened in the first half.
In pseudo-code something like this
function somethingRecursive(stuff):
beforeRecursive(stuff)
somethingRecursive(whatever)
afterRecursive(stuff)
becomes something like this:
while actions:
action = actions.pop()
if action.unwind:
afterRecursive(action.stuff)
else:
beforeRecursive(action.stuff)
actions.push(new Action(unwind, stuff))
actions.push(new Action(recurse, whatever))
Finally I got it working.
typedef struct
{
int uParam;
int vLocal;
int location;
}bpmState;
bool bpm_nr(bool bpGraph[M][N], int uParam, int matchR[])
{
bool seen[N];
memset(seen, 0, sizeof(seen));
stack<bpmState> states;
states.push({ uParam, 0, 1 });
bool rvalue = false;
while (!states.empty())
{
auto state = states.top();
states.pop();
switch (state.location)
{
case 1:
for (int v = state.vLocal, u = state.uParam; v < N; v++)
{
if (bpGraph[u][v] && !seen[v])
{
seen[v] = true;
if (matchR[v] < 0)
{
matchR[v] = u;
rvalue = true;
}
else
{
states.push({ u, v, 2 });
states.push({ matchR[v], 0, 1 });
}
break;
}
}
break;
case 2:
if (rvalue)
{
matchR[state.vLocal] = state.uParam;
rvalue = true;
}
else
{
states.push({ state.uParam, state.vLocal + 1, 1 });
}
break;
}
}
return rvalue;
}

print all nodes at a distance of 'x' from a given node in BST

The detailed question is to find all the nodes with distance x( i.e. number of edges =x) from a given node .
I was asked in an Amazon Interview today,
void findNodeWithDistanceX(struct node* root,struct node * qnode, int value)
{
//root is root Node, qnode is questionnode from which distance to be calculated, value is the
//distance to be calculated
//finding distance between root and qnode
int distance = findDistancefromRoot(root ,qnode);
if(distance> value)
{
traverseDistancedown(root ,distance-value);
}
if(distance ==value){
printf("%d",root->value);
}
// Traverse and find all nodes with distance value from 'qnode' down the tree
traverseDistancedown(qnode,value);
Now In case of finding the distance "value" from qnode .
I did not get the answer how to traverse up the Tree and satisfy the condition of distance with value.
Although many cases arises here.
I tried backtracking from qnode but to no avail I was unable to impress him and unable to write the Code.
Any Discussion regarding implementing the traversal up the tree will be helpful to me.
The simplest way is with a depth-first search, keeping track of the distance as you go along. It's a simple pre-order traversal starting at the "question node".
void nodesAtDistance(struct node* qnode, int requestedDistance, int currentDistance)
{
if (qnode == null) return;
if (currentDistance == requestedDistance)
{
// output qnode
// and then return because children are further away
return;
}
// visit left and then right
nodesAtDistance(qnode->left, requestedDistance, currentDistance+1);
nodesAtDistance(qnode->right, requestedDistance, currentDistance+1);
}
So if you call this with:
nodesAtDistance(myNode, 5, 0);
It will output all nodes that are 5 levels below myNode.
Now, if I were to write this as an API function, I would provide an overload that doesn't require the client to pass that currentDistance parameter. Because if somebody were to write nodesAtDistance(myNode, 5, 1), you'd get things at distance 4. So, create this overload:
void nodesAtDistance(node * qnode, int requestedDistance)
{
nodesAtDistance(qnode, requestedDistance, 0);
}
Make that function publicly visible, and make the other one private.
try this code, although this code checks only for children nodes and does not go back to check on ancestors nodes at given distance
#include<stdio.h>
#include<malloc.h>
struct treenode
{
unsigned int data;
struct treenode *left;
struct treenode *right;
};
struct treenode *treeptr, *sourcenode, *quesnode, *quesleftnode, *quesrightnode, *root = NULL;
struct node *treeptr insert_node(unsigned int treedata)
{
treeptr= (struct node*)(malloc(sizeof(treenode)));
treeptr->data = nodevalue;
treeptr->left = NULL;
treeptr->right = NULL;
return treeptr;
}
printnodesdistancek(struct treenode* quesnode, unsigned char reqdist)
{
unsigned char curdist=0;
do
{
if(quesnode == null)
return;
quesleftnode = quesnode->left;
if(curdist == reqdist)
{
printf("%d",quesleftnode->data);
}
else
{
quesnode= quesnode->left;
}
quesrightnode = quesnode->right;
if(curdist == reqdist)
{
printf("%d",quesrightnode->data);
}
else
{
quesnode = quesnode->right;
}
}while(quesnode!=NULL);
//main function
void main(void)
{
//create tree
*root = insert_node(1);
root->left=insert_node(-1);
root->right=insert_node(2);
root->left->left=insert_node(-2);
root->left->right=insert_node(3);
root->right->left=insert_node(-3);
root->right->right=insert_node(4);
sourcenode = root->left;
printnodesdistancek(sourcenode,1);
}

Looking at Sorts - Quicksort Iterative?

I'm looking at all different sorts. Note that this is not homework (I'm in the midst of finals) I'm just looking to be prepared if that sort of thing would pop up.
I was unable to find a reliable method of doing a quicksort iteratively. Is it possible and, if so, how?
I'll try to give a more general answer in addition to the actual implementations given in the other posts.
Is it possible and, if so, how?
Let us first of all take a look at what can be meant by making a recursive algorithm iterative.
For example, we want to have some function sum(n) that sums up the numbers from 0 to n.
Surely, this is
sum(n) =
if n = 0
then return 0
else return n + sum(n - 1)
As we try to compute something like sum(100000), we'll soon see this recursive algorithm has it's limits - a stack overflow will occur.
So, as a solution, we use an iterative algorithm to solve the same problem.
sum(n) =
s <- 0
for i in 0..n do
s <- s + i
return s
However, it's important to note that this implementation is an entirely different algorithm than the recursive sum above. We didn't in some way modify the original one to obtain the iterative version, we basically just found a non-recursive algorithm - with different and arguably better performance characteristics - that solves the same problem.
This is the first aspect of making an algorithm iterative: Finding a different, iterative algorithm that solves the same problem.
In some cases, there simply might not be such an iterative version.
The second one however is applicable to every recursive algorithm. You can turn any recursion into iteration by explicitly introducing the stack the recursion uses implicitly. Now this algorithm will have the exact same characteristics as the original one - and the stack will grow with O(n) like in the recursive version. It won't that easily overflow since it uses conventional memory instead of the call stack, and its iterative, but it's still the same algorithm.
As to quick sort: There is no different formulation what works without storing the data needed for recursion. But of course you can use an explicit stack for them like Ehsan showed. Thus you can - as always - produce an iterative version.
#include <stdio.h>
#include <conio.h>
#define MAXELT 100
#define INFINITY 32760 // numbers in list should not exceed
// this. change the value to suit your
// needs
#define SMALLSIZE 10 // not less than 3
#define STACKSIZE 100 // should be ceiling(lg(MAXSIZE)+1)
int list[MAXELT+1]; // one extra, to hold INFINITY
struct { // stack element.
int a,b;
} stack[STACKSIZE];
int top=-1; // initialise stack
int main() // overhead!
{
int i=-1,j,n;
char t[10];
void quicksort(int);
do {
if (i!=-1)
list[i++]=n;
else
i++;
printf("Enter the numbers <End by #>: ");
fflush(stdin);
scanf("%[^\n]",t);
if (sscanf(t,"%d",&n)<1)
break;
} while (1);
quicksort(i-1);
printf("\nThe list obtained is ");
for (j=0;j<i;j++)
printf("\n %d",list[j]);
printf("\n\nProgram over.");
getch();
return 0; // successful termination.
}
void interchange(int *x,int *y) // swap
{
int temp;
temp=*x;
*x=*y;
*y=temp;
}
void split(int first,int last,int *splitpoint)
{
int x,i,j,s,g;
// here, atleast three elements are needed
if (list[first]<list[(first+last)/2]) { // find median
s=first;
g=(first+last)/2;
}
else {
g=first;
s=(first+last)/2;
}
if (list[last]<=list[s])
x=s;
else if (list[last]<=list[g])
x=last;
else
x=g;
interchange(&list[x],&list[first]); // swap the split-point element
// with the first
x=list[first];
i=first+1; // initialise
j=last+1;
while (i<j) {
do { // find j
j--;
} while (list[j]>x);
do {
i++; // find i
} while (list[i]<x);
interchange(&list[i],&list[j]); // swap
}
interchange(&list[i],&list[j]); // undo the extra swap
interchange(&list[first],&list[j]); // bring the split-point
// element to the first
*splitpoint=j;
}
void push(int a,int b) // push
{
top++;
stack[top].a=a;
stack[top].b=b;
}
void pop(int *a,int *b) // pop
{
*a=stack[top].a;
*b=stack[top].b;
top--;
}
void insertion_sort(int first,int last)
{
int i,j,c;
for (i=first;i<=last;i++) {
j=list[i];
c=i;
while ((list[c-1]>j)&&(c>first)) {
list[c]=list[c-1];
c--;
}
list[c]=j;
}
}
void quicksort(int n)
{
int first,last,splitpoint;
push(0,n);
while (top!=-1) {
pop(&first,&last);
for (;;) {
if (last-first>SMALLSIZE) {
// find the larger sub-list
split(first,last,&splitpoint);
// push the smaller list
if (last-splitpoint<splitpoint-first) {
push(first,splitpoint-1);
first=splitpoint+1;
}
else {
push(splitpoint+1,last);
last=splitpoint-1;
}
}
else { // sort the smaller sub-lists
// through insertion sort
insertion_sort(first,last);
break;
}
}
} // iterate for larger list
}
// End of code.
taken from here
I was unable to find a reliable method of doing a quicksort iteratively
Have you tried google ?
It is just common quicksort, when recursion is realized with array.
This is my effort. Tell me if there is any improvement possible.
This code is done from the book "Data Structures, Seymour Lipschutz(Page-173), Mc GrawHill, Schaum's Outline Series."
#include <stdio.h>
#include <conio.h>
#include <math.h>
#define SIZE 12
struct StackItem
{
int StartIndex;
int EndIndex;
};
struct StackItem myStack[SIZE * SIZE];
int stackPointer = 0;
int myArray[SIZE] = {44,33,11,55,77,90,40,60,99,22,88,66};
void Push(struct StackItem item)
{
myStack[stackPointer] = item;
stackPointer++;
}
struct StackItem Pop()
{
stackPointer--;
return myStack[stackPointer];
}
int StackHasItem()
{
if(stackPointer>0)
{
return 1;
}
else
{
return 0;
}
}
void ShowStack()
{
int i =0;
printf("\n");
for(i=0; i<stackPointer ; i++)
{
printf("(%d, %d), ", myStack[i].StartIndex, myStack[i].EndIndex);
}
printf("\n");
}
void ShowArray()
{
int i=0;
printf("\n");
for(i=0 ; i<SIZE ; i++)
{
printf("%d, ", myArray[i]);
}
printf("\n");
}
void Swap(int * a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
int Scan(int *startIndex, int *endIndex)
{
int partition = 0;
int i = 0;
if(*startIndex > *endIndex)
{
for(i=*startIndex ; i>=*endIndex ; i--)
{
//printf("%d->", myArray[i]);
if(myArray[i]<myArray[*endIndex])
{
//printf("\nSwapping %d, %d", myArray[i], myArray[*endIndex]);
Swap(&myArray[i], &myArray[*endIndex]);
*startIndex = *endIndex;
*endIndex = i;
partition = i;
break;
}
if(i==*endIndex)
{
*startIndex = *endIndex;
*endIndex = i;
partition = i;
}
}
}
else if(*startIndex < *endIndex)
{
for(i=*startIndex ; i<=*endIndex ; i++)
{
//printf("%d->", myArray[i]);
if(myArray[i]>myArray[*endIndex])
{
//printf("\nSwapping %d, %d", myArray[i], myArray[*endIndex]);
Swap(&myArray[i], &myArray[*endIndex]);
*startIndex = *endIndex;
*endIndex = i;
partition = i;
break;
}
if(i==*endIndex)
{
*startIndex = *endIndex;
*endIndex = i;
partition = i;
}
}
}
return partition;
}
int GetFinalPosition(struct StackItem item1)
{
struct StackItem item = {0};
int StartIndex = item1.StartIndex ;
int EndIndex = item1.EndIndex;
int PivotIndex = -99;
while(StartIndex != EndIndex)
{
PivotIndex = Scan(&EndIndex, &StartIndex);
printf("\n");
}
return PivotIndex;
}
void QuickSort()
{
int median = 0;
struct StackItem item;
struct StackItem item1={0};
struct StackItem item2={0};
item.StartIndex = 0;
item.EndIndex = SIZE-1;
Push(item);
while(StackHasItem())
{
item = Pop();
median = GetFinalPosition(item);
if(median>=0 && median<=(SIZE-1))
{
if(item.StartIndex<=(median-1))
{
item1.StartIndex = item.StartIndex;
item1.EndIndex = median-1;
Push(item1);
}
if(median+1<=(item.EndIndex))
{
item2.StartIndex = median+1;
item2.EndIndex = item.EndIndex;
Push(item2);
}
}
ShowStack();
}
}
main()
{
ShowArray();
QuickSort();
ShowArray();
}

Resources