I am trying vertex cover problem. Even an imperfect code cleared all the cases on soj judge, but I got one test case (in comments) where it failed, so I tried to remove it. But, now its not accepting. Problem Link
Problem Description: You have to find the vertex cover of a wneighted, undirected tree i.e. to find a vertex set of minimum size in this tree such that each edge has as least one of its end-points in that set.
My Algorithm is based on DFS. Earlier I used a straightforward logic that, do DFS and while backtracking, if child vertex is not included, include its parent (if not already included). And, it got accepted. But, then it failed on a simple case of skewed tree with 6 vertex. The answer should be 2, but it was giving 3. So, I made slight modification.
I added another parameter to check if a vertex is already covered by its parent or its child, and if so, neglect. So, whenever a find a vertex not covered yet, I add it's parent in the vertex set.
My Old Source Code:
vector<int> edge[100000]; // to store edges
bool included[100000]; // to keep track of elements in vertex cover set
bool done[100000]; // to keep track of undiscivered nodes to do DFS on tree
int cnt; // count the elements in vertex set
/* Function performs DFS and makes a vertex cover set */
bool solve(int source){
done[source] = true;
for(unsigned int i = 0; i<edge[source].size(); ++i){
if(!done[edge[source][i]]){ // if node is undiscovered
if(!solve(edge[source][i]) && !included[source]){ // if child node is not included and neither its parent
included[source] = true; // element added to vertex cover set
cnt++; // increasing the size of set
}
}
}
return included[source]; // return the status of current source vertex
}
int main(){
int n,u,v;
scanint(n);
for(int i = 0; i<n-1; ++i){
done[i] = false;
included[i] = false;
scanint(u);
scanint(v);
edge[u-1].push_back(v-1);
edge[v-1].push_back(u-1);
}
done[n-1] = false;
included[n-1] = false;
cnt = 0;
solve(0);
printf("%d\n", cnt);
return 0;
}
My New Source Code:
vector<int> edge[100000]; // to store edges
bool incld[100000]; // to keep track of nodes in vertex cover set
bool covrd[100000]; // to keep track of nodes already covered
bool done[100000]; // to keep track of undiscovered nodes to perform DFS
int cnt; // keep track of size of vertex cover set
/* Function to calculate vertex cover set via DFS */
void solve(int source){
int child; // to store index of child node
done[source] = true;
for(unsigned int i = 0; i<edge[source].size(); ++i){
if(!done[edge[source][i]]){ // if child node is undiscovered
child = edge[source][i];
if(incld[child]) // if child node is included in vertex set
covrd[source] = true; // setting current node to be covered
else if(!covrd[child] && !incld[source]){ // if child node is not covered and current node is not included in vertex set
incld[source] = true; // including current node
covrd[child] = true; // covering child node
cnt++; // incrementing size of vertex cover set
}
}
}
}
int main(){
int n,u,v;
scanint(n);
for(int i = 0; i<n-1; ++i){
done[i] = false;
incld[i] = false;
covrd[i] = false;
scanint(u);
scanint(v);
edge[u-1].push_back(v-1);
edge[v-1].push_back(u-1);
}
done[n-1] = false;
incld[n-1] = false;
covrd[n-1] = false;
cnt = 0;
solve(0);
printf("%d\n", cnt);
return 0;
}
Please help.
Your first solution is correct(you can find a proof here). The answer for a skewed tree with 6 vertices is actually 3(the comment in the link which says that the answer is 2 is wrong).
Related
Multiple nodes can also be traversed in sequence to create a path.
struct Node {
float pos [2];
bool visited = false;
};
// Search Space
Node nodes [MAX_NODE_COUNT];
// Function to return all reachable nodes
// nodeCount : Number of nodes
// nodes : Array of nodes
// indexCount : Size of the returned array
// Return : Returns array of all reachable node indices
int* GetReachableNodes (int nodeCount, Node* nodes, int* indexCount)
{
// This is the naive approach
queue <int> indices;
vector <int> indexList;
indices.push (nodes [0]);
nodes [0].visited = true;
// Loop while queue is not empty
while (!indices.empty ())
{
// Pop the front of the queue
int parent = indices.front ();
indices.pop ();
// Loop through all children
for (int i = 0; i < nodeCount; ++i)
{
if (!nodes [i].visited && i != parent && DistanceSqr (nodes [i], nodes [parent]) < maxDistanceSqr)
{
indices.push (i);
nodes [i].visited = true;
indexList.push_back (i);
}
}
}
int* returnData = new int [indexList.size ()];
std::move (indexList.begin (), indexList.end (), returnData);
*indexCount = indexList.size ();
// Caller responsible for delete
return returnData;
}
The problem is I can't use a graph since all nodes are connected to each other.
All the data is just an array of nodes with their positions and the start node.
I can solve this problem easily with BFS but it's n^2.
I have been figuring out how to solve this in less than O(n^2) time complexity.
Some of the approaches I tried were parallel BFS, Dijkstra but it doesn't help a lot.
Any help will be really appreciated.
I have read an article from here about how to detect cycle in a directed graph. The basic concept of this algorithm is if a node is found in recursive stack then there is a cycle, but i don't understand why. what is the logic here?
#include<iostream>
#include <list>
#include <limits.h>
using namespace std;
class Graph
{
int V; // No. of vertices
list<int> *adj; // Pointer to an array containing adjacency lists
bool isCyclicUtil(int v, bool visited[], bool *rs);
public:
Graph(int V); // Constructor
void addEdge(int v, int w); // to add an edge to graph
bool isCyclic(); // returns true if there is a cycle in this graph
};
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.
}
bool Graph::isCyclicUtil(int v, bool visited[], bool *recStack)
{
if(visited[v] == false)
{
// Mark the current node as visited and part of recursion stack
visited[v] = true;
recStack[v] = true;
// 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] && isCyclicUtil(*i, visited, recStack) )
return true;
else if (recStack[*i])
return true;
}
}
recStack[v] = false; // remove the vertex from recursion stack
return false;
}
bool Graph::isCyclic()
{
// Mark all the vertices as not visited and not part of recursion
// stack
bool *visited = new bool[V];
bool *recStack = new bool[V];
for(int i = 0; i < V; i++)
{
visited[i] = false;
recStack[i] = false;
}
for(int i = 0; i < V; i++)
if (isCyclicUtil(i, visited, recStack))
return true;
return false;
}
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);
if(g.isCyclic())
cout << "Graph contains cycle";
else
cout << "Graph doesn't contain cycle";
return 0;
}
From a brief look, the code snippet is an implementation of depth-first search, which is a basic search technique for directed graphs; the same approach works for breadth-first search. Note that apparently this implementation works only if there is only one connected component, otherwise the test must be performed for each connected component until a cycle is found.
That being said, the technique works by choosing one node at will and starting a recursive search there. Basically, if the search discovers a node that is in the stack, there must be a cycle, since it has been previously reached.
In the current implementation, recStack is not actually the stack, it just indicates whether a specific node is currently in the stack, no sequence information is stored. The actual cycle is contained implicitly in the call stack. The cycle is the sequence of nodes for which the calls of isCyclicUtil has not yet returned. If the actual cycle has to be extracted, the implementation must be changed.
So essentailly, what this is saying, is if a node leads to itself, there is a cycle. This makes sense if you think about it!
Say we start at node1.
{node1 -> node2}
{node2 -> node3}
{node3 -> node4
node3 -> node1}
{node4 -> end}
{node1 -> node2}
{node2 -> node3}.....
This is a small graph that contains a cycle. As you can see, we traverse the graph, going from each node to the next. In some cases we reach and end, but even if we reach the end, our code wants to go back to the other branch off of node3 so that it can check it's next node. This node then leads back to node1.
This will happen forever if we let it, because the path starting at node1 leads back to itself. We are recursively putting each node we visit on the stack, and if we reach an end, we remove all of the nodes from the stack AFTER the branch. In our case, we would be removing node4 from the stack every time we hit the end, but the rest of the nodes would stay on the stack because of the branch off of node3.
Hope this helps!
I am trying to solve this question.
I am able to find by seeing the degrees that the given structure can form euler circuit or not but I am unable to figure out how to find trace all path, for the given test case
5
2 1
2 2
3 4
3 1
2 4
there is one loop in the circuit at node 2, which I don't know how to trace, If I am using adjacency list representation then I'll get following list
1: 2,3
2: 1,2,2,4
3: 1,4
4: 2,3
So how to traverse every edge, I know it is euler circuit problem, but that self loop thing is making tough for me to code and I am not getting any tutorial or blog from where I can understand this thing.
I again thought to delete the nodes from adjacency list once I traverse that path( in order to maintain the property of euler(path should be traversed once)), but I am using vector for storing adjacency list and I don't know how to delete particular element from vector. I googled it and found remove command to delete from vectors but remove deletes all matching element from the vector.
I tried to solve the problem as below now, but getting WA :(
#include<iostream>
#include<cstdio>
#include<cstring>
int G[52][52];
int visited[52],n;
void printadj() {
int i,j;
for(i=0;i<51;i++) {
for(j=0;j<51;j++)
printf("%d ",G[i][j]);
printf("\n");
}
}
void dfs(int u){
int v;
for(v=0;v<51;v++){
if(G[u][v]){
G[u][v]--;
G[v][u]--;
printf("%d %d\n",u,v);
dfs(v);
}
}
}
bool is_euler(){
int i,j,colsum=0,count=0;
for(i=0;i<51;i++) {
colsum=0;
for(j=0;j<51;j++) {
if(G[i][j] > 0) {
colsum+=G[i][j];
}
}
if(colsum%2!=0) count++;
}
// printf("\ncount=%d\n",count);
if(count >0 ) return false;
else return true;
}
void reset(){
int i,j;
for(i=0;i<51;i++)
for(j=0;j<51;j++)
G[i][j]=0;
}
int main(){
int u,v,i,t,k;
scanf("%d",&t);
for(k=0;k<t;k++) {
scanf("%d",&n);
reset();
for(i=0;i<n;i++){
scanf("%d%d",&u,&v);
G[u][v]++;
G[v][u]++;
}
// printadj();
printf("Case #%d\n",k+1);
if(is_euler()) {
dfs(u);
}
else printf("some beads may be lost\n");
printf("\n");
}
return 0;
}
Dont know why getting WA :(
New Code:-
#include<iostream>
#include<cstdio>
#include<cstring>
#define max 51
int G[max][max],print_u[max],print_v[max],nodes_traversed[max],nodes_found[max];
int n,m;
void printadj() {
int i,j;
for(i=0;i<max;i++) {
for(j=0;j<max;j++)
printf("%d ",G[i][j]);
printf("\n");
}
}
void dfs(int u){
int v;
for(v=0;v<50;v++){
if(G[u][v]){
G[u][v]--;
G[v][u]--;
print_u[m]=u;
print_v[m]=v;
m++;
dfs(v);
}
}
nodes_traversed[u]=1;
}
bool is_evendeg(){
int i,j,colsum=0,count=0;
for(i=0;i<50;i++) {
colsum=0;
for(j=0;j<50;j++) {
if(G[i][j] > 0) {
colsum+=G[i][j];
}
}
if(colsum&1) return false;
}
return true;
}
int count_vertices(int nodes[]){
int i,count=0;
for(i=0;i<51;i++) if(nodes[i]==1) count++;
return count;
}
void reset(){
int i,j;
m=0;
for(i=0;i<max;i++)
for(j=0;j<max;j++)
G[i][j]=0;
memset(print_u,0,sizeof(print_u));
memset(print_v,0,sizeof(print_v));
memset(nodes_traversed,0,sizeof(nodes_traversed));
memset(nodes_found,0,sizeof(nodes_found));
}
bool is_connected(int tot_nodes,int trav_nodes) {
if(tot_nodes == trav_nodes) return true;
else return false;
}
int main(){
int u,v,i,t,k,tot_nodes,trav_nodes;
scanf("%d",&t);
for(k=0;k<t;k++) {
scanf("%d",&n);
reset();
for(i=0;i<n;i++){
scanf("%d%d",&u,&v);
G[u][v]++;
G[v][u]++;
nodes_found[u]=nodes_found[v]=1;
}
// printadj();
printf("Case #%d\n",k+1);
tot_nodes=count_vertices(nodes_found);
if(is_evendeg()) {
dfs(u);
trav_nodes=count_vertices(nodes_traversed);
if(is_connected(tot_nodes,trav_nodes)) {
for(i=0;i<m;i++)
printf("%d %d\n",print_u[i],print_v[i]);
}
else printf("some beads may be lost\n");
}
else printf("some beads may be lost\n");
printf("\n");
}
return 0;
}
This code is giving me runtime error there, please look into the code.
What you need to do is form arbitrary cycles and then connect all cycles together. You seem to be doing only one depth first traversal, which might give you a Eulerian circuit, but it also may give you a 'shortcut' of an Eulerian circuit. That is because in every vertex where the Eulerian circuit passes more then once (i.e., where it crosses itself), when the depth first traversal arrives there for the first time, it may pick the edge that leads directly back to the start of the depth first traversal.
Thus, you're algorithm should consist of two parts:
Find all cycles
Connect the cycles together
If done right, you don't even have to check that all vertices have an even degree, instead you can rely on the fact that if step 1 or 2 cannot continue anymore, there exists no Eulerian cycle.
Reference Implementation (Java)
Since there's no language tag in your question, I'm going to assume that it's fine for you that I'll give you a Java reference implementation. Furthermore, I'll use the term 'node' instead of 'vertex', but that's just personal preference (it gives shorter code ;)).
I'll use one constant in this algorithm, which I will refer to from the other classes:
public static final int NUMBER_OF_NODES = 50;
Then, we'll need an Edge class to easily construct our cycles, which are basically linked lists of edges:
public class Edge
{
int u, v;
Edge prev, next;
public Edge(int u, int v)
{
this.u = u;
this.v = v;
}
/**
* Attaches a new edge to this edge, leading to the given node
* and returns the newly created Edge. The node where the
* attached edge starts doesn't need to be given, as it will
* always be the node where this edge ends.
*
* #param node The node where the attached edge ends.
*/
public Edge attach(int node)
{
next = new Edge(this.v, node);
next.prev = this;
return next;
}
}
Then, we'll need a Cycle class that can easily join two cycles:
public class Cycle
{
Edge start;
boolean[] used = new boolean[NUMBER_OF_NODES+1];
public Cycle(Edge start)
{
// Store the cycle itself
this.start = start;
// And memorize which nodes are being used in this cycle
used[start.u] = true;
for (Edge e = start.next; e != start; e = e.next)
used[e.u] = true;
}
/**
* Checks if this cycle can join with the given cycle. That is
* the case if and only if both cycles use a common node.
*
* #return {#code true} if this and that cycle can be joined,
* {#code false} otherwise.
*/
public boolean canJoin(Cycle that)
{
// Find a commonly used node
for (int node = 1; node <= NUMBER_OF_NODES; node++)
if (this.used[node] && that.used[node])
return true;
return false;
}
/**
* Joins the given cycle to this cycle. Both cycles will be broken
* at a common node and the paths will then be connected to each
* other. The given cycle should not be used after this call, as the
* list of used nodes is most probably invalidated, only this cycle
* will be updated and remains valid.
*
* #param that The cycle to be joined to this cycle.
*/
public void join(Cycle that)
{
// Find the node where we'll join the two cycles
int junction = 1;
while (!this.used[junction] || !that.used[junction])
junction++;
// Find the join place in this cycle
Edge joinAfterEdge = this.start;
while (joinAfterEdge.v != junction)
joinAfterEdge = joinAfterEdge.next;
// Find the join place in that cycle
Edge joinBeforeEdge = that.start;
while (joinBeforeEdge.u != junction)
joinBeforeEdge = joinBeforeEdge.next;
// Connect them together
joinAfterEdge.next.prev = joinBeforeEdge.prev;
joinBeforeEdge.prev.next = joinAfterEdge.next;
joinAfterEdge.next = joinBeforeEdge;
joinBeforeEdge.prev = joinAfterEdge;
// Update the used nodes
for (int node = 1; node <= NUMBER_OF_NODES; node++)
this.used[node] |= that.used[node];
}
#Override
public String toString()
{
StringBuilder s = new StringBuilder();
s.append(start.u).append(" ").append(start.v);
for (Edge curr = start.next; curr != start; curr = curr.next)
s.append("\n").append(curr.u).append(" ").append(curr.v);
return s.toString();
}
}
Now our utility classes are in place, we can write the actual algorithm (although technically, part of the algorithm is extending a path (Edge.attach(int node)) and joining two cycles (Cycle.join(Cycle that)).
/**
* #param edges A variant of an adjacency matrix: the number in edges[i][j]
* indicates how many links there are between node i and node j. Note
* that this means that every edge contributes two times in this
* matrix: one time from i to j and one time from j to i. This is
* also true in the case of a loop: the link still contributes in two
* ways, from i to j and from j to i, even though i == j.
*/
public static Cycle solve(int[][] edges)
{
Deque<Cycle> cycles = new LinkedList<Cycle>();
// First, find a place where we can start a new cycle
for (int u = 1; u <= NUMBER_OF_NODES; u++)
for (int v = 1; v <= NUMBER_OF_NODES; v++)
if (edges[u][v] > 0)
{
// The new cycle starts at the edge from u to v
Edge first, last = first = new Edge(u, v);
edges[last.u][last.v]--;
edges[last.v][last.u]--;
int curr = last.v;
// Extend the list of edges until we're back at the start
search: while (curr != u)
{
// Find any edge that extends the last edge
for (int next = 1; next <= NUMBER_OF_NODES; next++)
if (edges[curr][next] > 0)
{
// We found an edge, attach it to the last one
last = last.attach(next);
edges[last.u][last.v]--;
edges[last.v][last.u]--;
curr = next;
continue search;
}
// We can't form a cycle anymore, which
// means there is no Eulerian cycle.
return null;
}
// Connect the end to the start
last.next = first;
first.prev = last;
// Save it
cycles.add(new Cycle(last));
// And don't forget about the possibility that there are
// more edges running from u to v, so v should be
// re-examined in the next iteration.
v--;
}
// Now we have put all edges into cycles,
// we join them all together (if possible)
merge: while (cycles.size() > 1)
{
// Join the last cycle with any of the previous ones
Cycle last = cycles.removeLast();
for (Cycle curr : cycles)
if (curr.canJoin(last))
{
// Found one! Just join it and continue the merge
curr.join(last);
continue merge;
}
// No compatible cycle found, meaning there is no Eulerian cycle
return null;
}
return cycles.getFirst();
}
I need do find a cycle beginning and ending at given point. It is not guaranteed that it exists.
I use bool[,] points to indicate which point can be in cycle. Poins can be only on grid. points indicates if given point on grid can be in cycle.
I need to find this cycle using as minimum number of points.
One point can be used only once.
Connection can be only vertical or horizontal.
Let this be our points (red is starting point):
removing dead ImageShack links
I realized that I can do this:
while(numberOfPointsChanged)
{
//remove points that are alone in row or column
}
So i have:
removing dead ImageShack links
Now, I can find the path.
removing dead ImageShack links
But what if there are points that are not deleted by this loop but should not be in path?
I have written code:
class MyPoint
{
public int X { get; set; }
public int Y { get; set; }
public List<MyPoint> Neighbours = new List<MyPoint>();
public MyPoint parent = null;
public bool marked = false;
}
private static MyPoint LoopSearch2(bool[,] mask, int supIndexStart, int recIndexStart)
{
List<MyPoint> points = new List<MyPoint>();
//here begins translation bool[,] to list of points
points.Add(new MyPoint { X = recIndexStart, Y = supIndexStart });
for (int i = 0; i < mask.GetLength(0); i++)
{
for (int j = 0; j < mask.GetLength(1); j++)
{
if (mask[i, j])
{
points.Add(new MyPoint { X = j, Y = i });
}
}
}
for (int i = 0; i < points.Count; i++)
{
for (int j = 0; j < points.Count; j++)
{
if (i != j)
{
if (points[i].X == points[j].X || points[i].Y == points[j].Y)
{
points[i].Neighbours.Add(points[j]);
}
}
}
}
//end of translating
List<MyPoint> queue = new List<MyPoint>();
MyPoint start = (points[0]); //beginning point
start.marked = true; //it is marked
MyPoint last=null; //last point. this will be returned
queue.Add(points[0]);
while(queue.Count>0)
{
MyPoint current = queue.First(); //taking point from queue
queue.Remove(current); //removing it
foreach(MyPoint neighbour in current.Neighbours) //checking Neighbours
{
if (!neighbour.marked) //in neighbour isn't marked adding it to queue
{
neighbour.marked = true;
neighbour.parent = current;
queue.Add(neighbour);
}
//if neighbour is marked checking if it is startig point and if neighbour's parent is current point. if it is not that means that loop already got here so we start searching parents to got to starting point
else if(!neighbour.Equals(start) && !neighbour.parent.Equals(current))
{
current = neighbour;
while(true)
{
if (current.parent.Equals(start))
{
last = current;
break;
}
else
current = current.parent;
}
break;
}
}
}
return last;
}
But it doesn't work. The path it founds contains two points: start and it's first neighbour.
What am I doing wrong?
EDIT:
Forgot to mention... After horizontal connection there has to be vertical, horizontal, vertical and so on...
What is more in each row and column there need to be max two points (two or none) that are in the cycle. But this condition is the same as "The cycle has to be the shortest one".
First of all, you should change your representation to a more efficient one. You should make vertex a structure/class, which keeps the list of the connected vertices.
Having changed the representation, you can easily find the shortest cycle using breadth-first search.
You can speed the search up with the following trick: traverse the graph in the breadth-first order, marking the traversed vertices (and storing the "parent vertex" number on the way to the root at each vertex). AS soon as you find an already marked vertex, the search is finished. You can find the two paths from the found vertex to the root by walking back by the stored "parent" vertices.
Edit:
Are you sure you code is right? I tried the following:
while (queue.Count > 0)
{
MyPoint current = queue.First(); //taking point from queue
queue.Remove(current); //removing it
foreach (MyPoint neighbour in current.Neighbours) //checking Neighbours
{
if (!neighbour.marked) //if neighbour isn't marked adding it to queue
{
neighbour.marked = true;
neighbour.parent = current;
queue.Add(neighbour);
}
else if (!neighbour.Equals(current.parent)) // not considering own parent
{
// found!
List<MyPoint> loop = new List<MyPoint>();
MyPoint p = current;
do
{
loop.Add(p);
p = p.parent;
}
while (p != null);
p = neighbour;
while (!p.Equals(start))
{
loop.Add(p);
p = p.parent;
}
return loop;
}
}
}
return null;
instead of the corresponding part in your code (I changed the return type to List<MyPoint>, too). It works and correctly finds a smaller loop, consisting of 3 points: the red point, the point directly above and the point directly below.
That is what I have done. I don't know if it is optimised but it does work correctly. I have not done the sorting of the points as #marcog suggested.
private static bool LoopSearch2(bool[,] mask, int supIndexStart, int recIndexStart, out List<MyPoint> path)
{
List<MyPoint> points = new List<MyPoint>();
points.Add(new MyPoint { X = recIndexStart, Y = supIndexStart });
for (int i = 0; i < mask.GetLength(0); i++)
{
for (int j = 0; j < mask.GetLength(1); j++)
{
if (mask[i, j])
{
points.Add(new MyPoint { X = j, Y = i });
}
}
}
for (int i = 0; i < points.Count; i++)
{
for (int j = 0; j < points.Count; j++)
{
if (i != j)
{
if (points[i].X == points[j].X || points[i].Y == points[j].Y)
{
points[i].Neighbours.Add(points[j]);
}
}
}
}
List<MyPoint> queue = new List<MyPoint>();
MyPoint start = (points[0]);
start.marked = true;
queue.Add(points[0]);
path = new List<MyPoint>();
bool found = false;
while(queue.Count>0)
{
MyPoint current = queue.First();
queue.Remove(current);
foreach (MyPoint neighbour in current.Neighbours)
{
if (!neighbour.marked)
{
neighbour.marked = true;
neighbour.parent = current;
queue.Add(neighbour);
}
else
{
if (neighbour.parent != null && neighbour.parent.Equals(current))
continue;
if (current.parent == null)
continue;
bool previousConnectionHorizontal = current.parent.Y == current.Y;
bool currentConnectionHorizontal = current.Y == neighbour.Y;
if (previousConnectionHorizontal != currentConnectionHorizontal)
{
MyPoint prev = current;
while (true)
{
path.Add(prev);
if (prev.Equals(start))
break;
prev = prev.parent;
}
path.Reverse();
prev = neighbour;
while (true)
{
if (prev.Equals(start))
break;
path.Add(prev);
prev = prev.parent;
}
found = true;
break;
}
}
if (found) break;
}
if (found) break;
}
if (path.Count == 0)
{
path = null;
return false;
}
return true;
}
Your points removal step is worst case O(N^3) if implemented poorly, with the worst case being stripping a single point in each iteration. And since it doesn't always save you that much computation in the cycle detection, I'd avoid doing it as it also adds an extra layer of complexity to the solution.
Begin by creating an adjacency list from the set of points. You can do this efficiently in O(NlogN) if you sort the points by X and Y (separately) and iterate through the points in order of X and Y. Then to find the shortest cycle length (determined by number of points), start a BFS from each point by initially throwing all points on the queue. As you traverse an edge, store the source of the path along with the current point. Then you will know when the BFS returns to the source, in which case we've found a cycle. If you end up with an empty queue before finding a cycle, then none exists. Be careful not to track back immediately to the previous point or you will end up with a defunct cycle formed by two points. You might also want to avoid, for example, a cycle formed by the points (0, 0), (0, 2) and (0, 1) as this forms a straight line.
The BFS potentially has a worst case of being exponential, but I believe such a case can either be proven to not exist or be extremely rare as the denser the graph the quicker you'll find a cycle while the sparser the graph the smaller your queue will be. On average it is more likely to be closer to the same runtime as the adjacency list construction, or in the worst realistic cases O(N^2).
I think that I'd use an adapted variant of Dijkstra's algorithm which stops and returns the cycle whenever it arrives to any node for the second time. If this never happens, you don't have a cycle.
This approach should be much more efficient than a breadth-first or depth-first search, especially if you have many nodes. It is guarateed that you'll only visit each node once, thereby you have a linear runtime.
I need to write a program that check if a graph is bipartite.
I have read through wikipedia articles about graph coloring and bipartite graph. These two article suggest methods to test bipartiteness like BFS search, but I cannot write a program implementing these methods.
Why can't you? Your question makes it hard for someone to even write the program for you since you don't even mention a specific language...
The idea is to start by placing a random node into a FIFO queue (also here). Color it blue. Then repeat this while there are nodes still left in the queue: dequeue an element. Color its neighbors with a different color than the extracted element and insert (enqueue) each neighbour into the FIFO queue. For example, if you dequeue (extract) an element (node) colored red, color its neighbours blue. If you extract a blue node, color its neighbours red. If there are no coloring conflicts, the graph is bipartite. If you end up coloring a node with two different colors, than it's not bipartite.
Like #Moron said, what I described will only work for connected graphs. However, you can apply the same algorithm on each connected component to make it work for any graph.
http://www.personal.kent.edu/~rmuhamma/Algorithms/MyAlgorithms/GraphAlgor/breadthSearch.htm
Please read this web page, using breadth first search to check when you find a node has been visited, check the current cycle is odd or even.
A graph is bipartite if and only if it does not contain an odd cycle.
The detailed implementation is as follows (C++ version):
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;
}