I am implementing an algorithm to determine whether an undirected graph is bipartite or not. Based on this pseudo-code made my implementation, which works for graphs connected, but when it is disconnected simply the program indicates a wrong answer. I think if its not connected, then one more loop is needed for every disjoint sub-graph. But im stuck with this. How I can solve my code for me to print a correct answer?
#include <cstdio>
#include <vector>
#include <queue>
#include <iostream>
using namespace std;
#define MAX 1000
int numberVertex, numberEdges;
int particion[MAX], visited[MAX];
vector< int > adjacencyMatrix[MAX];
bool bfs()
{
int i, origin, destination, begin;
queue< int > queueVertex;
begin = 0;
queueVertex.push(begin);
particion[begin] = 1; // 1 left,
visited[begin] = 1; // set adjacencyMatrixray
while(!queueVertex.empty())
{
origin = queueVertex.front(); queueVertex.pop();
for(i=0; i < adjacencyMatrix[origin].size(); i++)
{
destination = adjacencyMatrix[origin][i];
if(particion[origin] == particion[destination])
{
return false;
}
if(visited[destination] == 0)
{
visited[destination] = 1;
particion[destination] = 3 - particion[origin]; // alter 1 and 2 subsets
queueVertex.push(destination);
}
}
}
return true;
}
int main()
{
freopen("tarea2.in", "r", stdin);
int i,j, nodeOrigin, nodeDestination;
scanf("%d %d", &numberVertex, &numberEdges);
for(i=0; i<numberEdges; i++)
{
scanf("%d %d", &nodeOrigin, &nodeDestination);
adjacencyMatrix[nodeOrigin].push_back(nodeDestination);
adjacencyMatrix[nodeDestination].push_back(nodeOrigin);
}
if(bfs()) {
printf("Is bipartite\n");
for (j=0; j<numberVertex; j++){
cout<<j<<" "<<particion[j]<<endl;
}
}
else {printf("Is not bipartite\n");}
return 0;
}
For example for this input
6 4
3 0
1 0
2 5
5 4
the output should be:
Is bipartite
0 1
1 2
2 1
3 2
4 1
5 2
Instead throws me the output:
0 1
1 2
2 0
3 2
4 0
5 0
This happens because the graph is not a connected graph, ie, has two connected components.I hope you can help me because I've been stuck with this for several days.
You should run bfs on every connected component. Simplest way to do this is to iterate over all vertices and if they weren't visited, then just call bfs on them.
bool is_bipartite()
{
for(int i = 0; i < numberVertex; i++)
{
if (visited[i] == 0 && !bfs(i)) {
return false;
}
}
return true;
}
It is still linear because, you run bfs on every connected component once.
#include <cstdio>
#include <vector>
#include <queue>
#include <iostream>
using namespace std;
#define MAX 1000
int numberVertex, numberEdges;
int particion[MAX], visited[MAX];
vector< int > adjacencyMatrix[MAX];
bool bfs(int begin)
{
int i, origin, destination;
queue< int > queueVertex;
queueVertex.push(begin);
particion[begin] = 1; // 1 left,
visited[begin] = 1; // set adjacencyMatrixray
while(!queueVertex.empty())
{
origin = queueVertex.front(); queueVertex.pop();
for(i=0; i < adjacencyMatrix[origin].size(); i++)
{
destination = adjacencyMatrix[origin][i];
if(particion[origin] == particion[destination])
{
return false;
}
if(visited[destination] == 0)
{
visited[destination] = 1;
particion[destination] = 3 - particion[origin]; // alter 1 and 2 subsets
queueVertex.push(destination);
}
}
}
return true;
}
bool is_bipartite()
{
for(int i=0; i< numberVertex; i++)
{
if (visited[i] == 0 && !bfs(i)) {
return false;
}
}
return true;
}
int main()
{
//freopen("tarea2.in", "r", stdin);
int i,j, nodeOrigin, nodeDestination;
scanf("%d %d", &numberVertex, &numberEdges);
for(i=0; i<numberEdges; i++)
{
scanf("%d %d", &nodeOrigin, &nodeDestination);
adjacencyMatrix[nodeOrigin].push_back(nodeDestination);
adjacencyMatrix[nodeDestination].push_back(nodeOrigin);
}
if(is_bipartite()) {
printf("Is bipartite\n");
for (j=0; j<numberVertex; j++){
cout<<j<<" "<<particion[j]<<endl;
}
}
else {printf("Is not bipartite\n");}
return 0;
}