Monday, March 15, 2010

Testing Bipartite Graph


We can use BFS to check whether an undirected graph is bipartite or not, with only a little modification...

We define bipartite graph as follows: A bipartite graph is an undirected graph G = (V, E) in which V can be partitioned into two sets V1 and V2 such that (u, v) ∈ E implies either u ∈ V1 and v ∈ V2 or u ∈ V2 and v ∈ V1. That is, all edges go between the two sets V1 and V2.

In other to determine if a graph G = (V, E) is bipartite, we perform a BFS on it with a little modification such that whenever the BFS is at a vertex u and encounters a vertex v that is already 'gray', i.e. visited, our modified BSF should check to see if the depth of both u and v are even, or if they are both odd. If either of these conditions holds which implies d[u] and d[v] have the same parity, then the graph is not bipartite. Note that this modification does not change the running time of BFS and remains Θ(V + E).

Here goes a simple implementation of the above idea. We'll just run a BFS, while tracking the partition in which every node falls. If, when visiting node v from node u, and they are members of same partition, then this graph is not bipartite. Well, this time, I think, we have nothing to do with the edge weights or costs, so it will also work on a weighted graph.

Formally, to check if the given graph is bipartite, the algorithm traverse the graph labelling the vertices 0 or 1 / 2 , corresponding to unvisited or visited, and partition 1 or partition 2 depending on which set the nodes are in. If an edge is detected between two vertices in the same partition, the algorithm returns false immediately.

Note: In this implementation, only one test at a time is possible, to run it for multiple cases, definitely cares must be taken about resetting the arrays and other values as necessary.

#include <cstdio>
#include <vector>
#include <queue>
using namespace std;

#define MAX 1001

int n, e;
int partition[MAX], visited[MAX];
vector< int > G[MAX];

bool is_bipartite()
{
int i, u, v, start;
queue< int > Q;
start = 1; // nodes labeled from 1
Q.push(start);
partition[start] = 1; // 1 left, 2 right
visited[start] = 1; // set gray

while(!Q.empty())
{
u = Q.front(); Q.pop();
for(i=0; i < G[u].size(); i++)
{
v = G[u][i];
if(partition[u] == partition[v]) return false;
if(visited[v] == 0)
{
visited[v] = 1;
partition[v] = 3 - partition[u]; // alter 1 and 2
Q.push(v);
}
}
}
return true;
}

int main()
{
int i, u, v;
scanf("%d %d", &n, &e);
for(i=0; i<e; i++)
{
scanf("%d %d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
if(is_bipartite()) printf("Yes\n");
else printf("No\n");
return 0;
}

As this algorithm traverses the graph it labels the vertices with a partition number consisted with the graph being bipartite. If at any vertex, algorithm detects an inconsistency, it shows with an invalid return value. Partition value of u will always be a valid number as it was en-queued at some point and its partition was assigned at that point. Partition of v will be unchanged if it is already set, otherwise it will be set to a value opposite to that of vertex u. So, if the algorithm returns true, it means, the graph is bipartite, i.e. bi-color-able, and partition[] holds the colors for each vertex.

Have fun, and let me know about errors, if any.
[Note: The definition of bipartite graph is taken from this wonderful site]

4 comments:

  1. You need one more loop (and may be some bookkeeping) - for a bipartite graph may not be a connected graph.

    ReplyDelete
  2. Oh, I forgot to write I assumed it to be connected one. Of course, if its not connected, then one more loop is needed for every disjoint sub-graph. Thanks :)

    ReplyDelete
  3. Dude,
    Your material(apart from the C programme) is almost the same as in
    http://www.personal.kent.edu/~rmuhamma/Algorithms/MyAlgorithms/GraphAlgor/breadthSearch.htm
    If you have used the material, better acknowledge it. Otherwise, you are in for some serious trouble.

    ReplyDelete
  4. @Anonymous, thanks for pointing it. I have copied the definition of bipartite graph from his site. Because, anyone anyhow writes it will pretty much be the same. And no, I am not in any kind of trouble. Because, there is no copy-write claim on his site. I like that site very much, and probably if you have not noticed, his site is listed in the right panel's "Favorite Links" section from the start of the blog. Thanks for your comment.

    ReplyDelete

Catagories

academic study (17) access modifiers (1) algorithm (28) bash (1) beginner (17) bfs (1) bigint (1) binary tree (1) bitwise (4) blogger (5) bpm (2) brainfuck (1) bst (1) c (1) c++ (36) changes (1) character device driver (1) combinatorics (2) command prompt (1) comparator (1) compression (1) computational geometry (2) confusion (1) contest (7) crc (1) cse (3) css (1) customize (1) data structure (10) database (1) decoding (1) design (1) device driver (1) divide and conquer (2) dp (3) driver (1) dynamic programming (9) encoding (1) encryption (1) error (2) esoteric language (2) euler circuit (1) euler path (1) executable (1) expression evaluation (1) extended euclid (1) facebook (1) factorization (1) funny (14) gcd (2) geometry (4) git (1) github (1) graph (7) hashing (1) hiding window (1) hints (5) hopcroft karp (1) huffman (1) jar (1) java (5) javascript (1) jdbc (1) kernel programming (2) lab (1) like (1) linear algebra (3) linux (5) ls (1) makefile (1) math (16) matrix (2) matrix algebra (1) matrix exponentiation (1) matrix multiplication (1) maxflow (1) maximum bipartite matching (2) maximum flow (1) merge sort (3) mistake (1) modular arithmatic (1) module compiling (2) mysql (1) number system (1) number theory (8) online judge (3) operating system (1) os (1) other (8) parallel programming (1) pollard rho (1) primes (3) problem (3) problem classifier (2) problem solving (34) programming (51) pthreaded (1) puzzle (1) python (3) recursion (5) repository (1) shell (1) shell script (1) sieve (1) simulation (1) sort (3) spacing (1) sphere online judge (12) spoj (12) syntax highlighting (1) system programming (4) table tag (1) tc (1) template (4) thread (1) topcoder (1) training (3) tree (1) tutorial (2) ubuntu (1) usaco (1) uva (5) uva online judge (5) vector (1) windows (1)