Given a weighted and undirected graph, we need to find if a cycle exist in this graph such that the sum of weights of all the edges in that cycle comes out to be odd.
Examples:
Input : Number of vertices, n = 4,
Number of edges, m = 4
Weighted Edges =
1 2 12
2 3 1
4 3 1
4 1 20
Output : No! There is no odd weight
cycle in the given graph

Input : Number of vertices, n = 5,
Number of edges, m = 3
Weighted Edges =
1 2 1
3 2 1
3 1 1
Output : Yes! There is an odd weight
cycle in the given graph
The solution is based on the fact that “If a graph has no odd length cycle then it must be Bipartite, i.e., it can be colored with two colors“
The idea is to convert given problem to a simpler problem where we have to just check if there is cycle of odd length or not. To convert, we do following
- Convert all even weight edges into two edges of unit weight.
- Convert all odd weight edges to a single edge of unit weight.
Let’s make an another graph for graph shown above (in example 1)

Here, edges [1 — 2] have be broken in two parts such that [1-pseudo1-2] a pseudo node has been introduced. We are doing this so that each of our even weighted edge is taken into consideration twice while the edge with odd weight is counted only once. Doing this would help us further when we color our cycle. We assign all the edges with weight 1 and then by using 2 color method traverse the whole graph.
Now we start coloring our modified graph using two colors only. In a cycle with even number of nodes, when we color it using two colors only, none of the two adjacent edges have the same color. While if we try coloring a cycle having odd number of edges, surely a situation arises where two adjacent edges have the same color. This is our pick! Thus, if we are able to color the modified graph completely using 2 colors only in a way no two adjacent edges get the same color assigned to them then there must be either no cycle in the graph or a cycle with even number of nodes. If any conflict arises while coloring a cycle with 2 colors only, then we have an odd cycle in our graph.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
bool twoColorUtil(vector< int >G[], int src, int N,
int colorArr[]) {
colorArr[src] = 1;
queue < int > q;
q.push(src);
while (!q.empty()){
int u = q.front();
q.pop();
for ( int v = 0; v < G[u].size(); ++v){
if (colorArr[G[u][v]] == -1){
colorArr[G[u][v]] = 1 - colorArr[u];
q.push(G[u][v]);
}
else if (colorArr[G[u][v]] == colorArr[u])
return false ;
}
}
return true ;
}
bool twoColor(vector< int >G[], int N){
int colorArr[N];
for ( int i = 1; i <= N; ++i)
colorArr[i] = -1;
for ( int i = 1; i <= N; i++)
if (colorArr[i] == -1)
if (twoColorUtil(G, i, N, colorArr) == false )
return false ;
return true ;
}
bool isOddSum( int info[][3], int n, int m){
vector< int > G[2*n];
int pseudo = n+1;
int pseudo_count = 0;
for ( int i=0; i<m; i++){
if (info[i][2]%2 == 1){
int u = info[i][0];
int v = info[i][1];
G[u].push_back(v);
G[v].push_back(u);
}
else {
int u = info[i][0];
int v = info[i][1];
G[u].push_back(pseudo);
G[pseudo].push_back(u);
G[v].push_back(pseudo);
G[pseudo].push_back(v);
pseudo_count++;
pseudo++;
}
}
return twoColor(G,n+pseudo_count);
}
int main() {
int n = 4, m = 4;
int info[4][3] = {{1, 2, 12},
{2, 3, 1},
{4, 3, 1},
{4, 1, 20}};
if (isOddSum(info, n, m) == true )
cout << "No\n" ;
else
cout << "Yes\n" ;
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG
{
static boolean twoColorUtil(Vector<Integer>[] G,
int src, int N,
int [] colorArr)
{
colorArr[src] = 1 ;
Queue<Integer> q = new LinkedList<>();
q.add(src);
while (!q.isEmpty())
{
int u = q.peek();
q.poll();
for ( int v = 0 ; v < G[u].size(); ++v)
{
if (colorArr[G[u].elementAt(v)] == - 1 )
{
colorArr[G[u].elementAt(v)] = 1 - colorArr[u];
q.add(G[u].elementAt(v));
}
else if (colorArr[G[u].elementAt(v)] == colorArr[u])
return false ;
}
}
return true ;
}
static boolean twoColor(Vector<Integer>[] G, int N)
{
int [] colorArr = new int [N + 1 ];
for ( int i = 1 ; i <= N; ++i)
colorArr[i] = - 1 ;
for ( int i = 1 ; i <= N; i++)
if (colorArr[i] == - 1 )
if (twoColorUtil(G, i, N, colorArr) == false )
return false ;
return true ;
}
static boolean isOddSum( int [][] info, int n, int m)
{
Vector<Integer>[] G = new Vector[ 2 * n];
for ( int i = 0 ; i < 2 * n; i++)
G[i] = new Vector<>();
int pseudo = n + 1 ;
int pseudo_count = 0 ;
for ( int i = 0 ; i < m; i++)
{
if (info[i][ 2 ] % 2 == 1 )
{
int u = info[i][ 0 ];
int v = info[i][ 1 ];
G[u].add(v);
G[v].add(u);
}
else
{
int u = info[i][ 0 ];
int v = info[i][ 1 ];
G[u].add(pseudo);
G[pseudo].add(u);
G[v].add(pseudo);
G[pseudo].add(v);
pseudo_count++;
pseudo++;
}
}
return twoColor(G, n + pseudo_count);
}
public static void main(String[] args)
{
int n = 4 , m = 3 ;
int [][] info = { { 1 , 2 , 12 }, { 2 , 3 , 1 },
{ 4 , 3 , 1 }, { 4 , 1 , 20 } };
if (isOddSum(info, n, m) == true )
System.out.println( "No" );
else
System.out.println( "Yes" );
}
}
|
Python3
def twoColorUtil(G, src, N, colorArr):
colorArr[src] = 1
q = [src]
while len (q) > 0 :
u = q.pop( 0 )
for v in range ( 0 , len (G[u])):
if colorArr[G[u][v]] = = - 1 :
colorArr[G[u][v]] = 1 - colorArr[u]
q.append(G[u][v])
elif colorArr[G[u][v]] = = colorArr[u]:
return False
return True
def twoColor(G, N):
colorArr = [ - 1 ] * N
for i in range (N):
if colorArr[i] = = - 1 :
if twoColorUtil(G, i, N, colorArr) = = False :
return False
return True
def isOddSum(info, n, m):
G = [[] for i in range ( 2 * n)]
pseudo, pseudo_count = n + 1 , 0
for i in range ( 0 , m):
if info[i][ 2 ] % 2 = = 1 :
u, v = info[i][ 0 ], info[i][ 1 ]
G[u].append(v)
G[v].append(u)
else :
u, v = info[i][ 0 ], info[i][ 1 ]
G[u].append(pseudo)
G[pseudo].append(u)
G[v].append(pseudo)
G[pseudo].append(v)
pseudo_count + = 1
pseudo + = 1
return twoColor(G, n + pseudo_count)
if __name__ = = "__main__" :
n, m = 4 , 3
info = [[ 1 , 2 , 12 ],
[ 2 , 3 , 1 ],
[ 4 , 3 , 1 ],
[ 4 , 1 , 20 ]]
if isOddSum(info, n, m) = = True :
print ( "No" )
else :
print ( "Yes" )
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static bool twoColorUtil(List< int >[] G,
int src, int N,
int [] colorArr)
{
colorArr[src] = 1;
List< int > q = new List< int >();
q.Add(src);
while (q.Count != 0)
{
int u = q[0];
q.RemoveAt(0);
for ( int v = 0; v < G[u].Count; ++v)
{
if (colorArr[G[u][v]] == -1)
{
colorArr[G[u][v]] = 1 - colorArr[u];
q.Add(G[u][v]);
}
else if (colorArr[G[u][v]] == colorArr[u])
return false ;
}
}
return true ;
}
static bool twoColor(List< int >[] G, int N)
{
int [] colorArr = new int [N + 1];
for ( int i = 1; i <= N; ++i)
colorArr[i] = -1;
for ( int i = 1; i <= N; i++)
if (colorArr[i] == -1)
if (twoColorUtil(G, i, N, colorArr) == false )
return false ;
return true ;
}
static bool isOddSum( int [,] info, int n, int m)
{
List< int >[] G = new List< int >[2 * n];
for ( int i = 0; i < 2 * n; i++)
G[i] = new List< int >();
int pseudo = n + 1;
int pseudo_count = 0;
for ( int i = 0; i < m; i++)
{
if (info[i, 2] % 2 == 1)
{
int u = info[i, 0];
int v = info[i, 1];
G[u].Add(v);
G[v].Add(u);
}
else
{
int u = info[i, 0];
int v = info[i, 1];
G[u].Add(pseudo);
G[pseudo].Add(u);
G[v].Add(pseudo);
G[pseudo].Add(v);
pseudo_count++;
pseudo++;
}
}
return twoColor(G, n + pseudo_count);
}
public static void Main(String[] args)
{
int n = 4, m = 3;
int [,] info = { { 1, 2, 12 }, { 2, 3, 1 },
{ 4, 3, 1 }, { 4, 1, 20 } };
if (isOddSum(info, n, m) == true )
Console.WriteLine( "No" );
else
Console.WriteLine( "Yes" );
}
}
|
Javascript
<script>
function twoColorUtil(G, src, N, colorArr)
{
colorArr[src] = 1;
var q = [];
q.push(src);
while (q.length != 0)
{
var u = q[0];
q.shift();
for ( var v = 0; v < G[u].length; ++v)
{
if (colorArr[G[u][v]] == -1)
{
colorArr[G[u][v]] = 1 - colorArr[u];
q.push(G[u][v]);
}
else if (colorArr[G[u][v]] == colorArr[u])
return false ;
}
}
return true ;
}
function twoColor(G, N)
{
var colorArr = Array(N+1).fill(-1);
for ( var i = 1; i <= N; i++)
if (colorArr[i] == -1)
if (twoColorUtil(G, i, N, colorArr) == false )
return false ;
return true ;
}
function isOddSum(info, n, m)
{
var G = Array.from(Array(2*n), ()=>Array());
var pseudo = n + 1;
var pseudo_count = 0;
for ( var i = 0; i < m; i++)
{
if (info[i][2] % 2 == 1)
{
var u = info[i][0];
var v = info[i][1];
G[u].push(v);
G[v].push(u);
}
else
{
var u = info[i][0];
var v = info[i][1];
G[u].push(pseudo);
G[pseudo].push(u);
G[v].push(pseudo);
G[pseudo].push(v);
pseudo_count++;
pseudo++;
}
}
return twoColor(G, n + pseudo_count);
}
var n = 4, m = 3;
var info = [ [ 1, 2, 12 ], [ 2, 3, 1 ],
[ 4, 3, 1 ], [ 4, 1, 20 ] ];
if (isOddSum(info, n, m) == true )
document.write( "No" );
else
document.write( "Yes" );
</script>
|
Time Complexity: O(N*N), as we are using a loop to traverse N times and in each traversal we are calling the function twoColorUtil which costs O(N) time.
Auxiliary Space: O(N), as we are using extra space.
This article is contributed by Parth Trehan. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.