Given an integer N denoting the total number of fights between empire A and B all together in a war zone, also given a 2-D array arr of size N denoting that soldier arr[i][0] and arr[i][1] are fighting with each other. The task is to find the maximum number of soldiers belonging to an empire if it is possible to distribute all the soldiers among A and B, otherwise print -1.
Example:
Input: N = 4, arr = [[1, 2], [2, 3], [2, 4], [2, 5]] Output: 4 Explanation: From the input we have following fight: {1, 3, 4, 6} fighting with {2} => maximum group of soldier = 4.
Input: N = 8, arr = [[1, 2], [2, 3], [3, 4], [3, 5], [6, 7], [7, 8], [7, 9], [7, 10]] Output: 7 Explanation: From the input we have following fights: {1, 3} fighting with {2, 4, 5} => maximum group of soldier=3 {6, 8, 9, 10} fighting with {7} => maximum group of soldier=4 Hence maximum number of soldier in an empire = 3+4 = 7
Input: N=3, arr=[[1, 2], [2, 3], [3, 1]] Output: -1 Explanation: it is impossible to distribute 1, 2 and 3 among A and B such that there is not a fight between soldier of same empire.
Approach: Using a Bipartite graph to solve the question as discussed below:
We can create a graph from the array 'arr' such that there is a bidirectional edge between arr[i][0] and arr[i][1] , then apply the Bipartite coloring on each component of the graph.
To get the answer pick the occurrence of the maximum occurring color of each component of the graph and add them together.
If in case for any component we can not color it using Bipartite coloring, then we return -1.
To solve this test case, firstly we can create a graph such that there is a bidirectional edge between arr[i][0] and arr[i][1] as shown in fig-1.
After applying Bipartite coloring on the graph (as shown in fig-1) we see that vertex {1, 6} have same color(blue) and vertex {2, 3, 4, 5} have same color(yellow). Since the frequency of Yellow color is more i.e. 4>2, hence for this graph we can conclude that maximum 4 number of soldier are in same team and return 4 as our answer.
fig-1
Now let's see a case when grouping of soldier into two empiers is immpossible and we return -1 as our answer. Suppose N=5, arr=[[1, 2],[2, 3],[3, 4],[4, 5],[5, 1]]
In this test case when when we apply Bipartite coloring (say on vertex 1) there will be 2 cases of coloring possible:
Case 1: node 4 and node 5 have same color and an edge between them.
Case 2: node 4 and node 3 have same color and an edge between them.
Both these cases are contradicting the Bipartite coloring and hence we return -1. In short Bipartite coloring is impossible for a graph having an odd length cycle. This case is clearly shown in fig-2.
fig-2
Follow the steps to solve the problem:
Create a graph 'g' such that arr[i][0] and arr[i][1] are vertices of that graph.
Keep track of all unique vertices in an array of 'soldiers[]'.
Create a 'colr[]' array initialized by '-1' to keep track of the color of each vertex.
Now apply Bipartite coloring on all the vertices which are not colored yet. For each component of the graph find the maximum occurrence of the color i.e. max(zero, one) (Note: zero and one represent two colors) and add that value to the answer 'ans'.
In case Bipartite coloring is not possible for any component set the 'flag' variable as false and return '-1'.
Below is the implementation of the above algorithm:
C++
// C++ code for the above approach#include<bits/stdc++.h>usingnamespacestd;// one and zero are our two colorsintone,zero;// Flag to check whether the answer// exists or notboolflag=true;voidBipartiteColor(intv,vector<vector<int>>&g,vector<int>&colr,intpaint){// if the vertex is already coloredif(colr[v]!=-1){// if previous color and current paint// contradict each other then our answer// won't existif(colr[v]!=paint)flag=false;return;}// paint the current vertex vcolr[v]=paint;// if paint is 1if(paint)one++;// if paint is 0elsezero++;// Recursive calls on the child of vertex vfor(autochild:g[v]){// Giving the complementory color to the// child i.e. if colr[v]=1 then// colr[child]=0 and vice verseBipartiteColor(child,g,colr,!paint);}}voidmaximumSoldier(intN,vector<vector<int>>arr){// Creating a graph// taking 20001 as the upper bound// for unique soldiers.vector<vector<int>>g(20001);// set to store all the unique soldiersset<int>st;for(inti=0;i<N;i++){// u and v stores the soldierintu,v;u=arr[i][0];v=arr[i][1];// Initializing the graphg[u].push_back(v);g[v].push_back(u);// Inserting u and v into setst.insert(u);st.insert(v);}// To store all the unique// soldiers of set stvector<int>soldiers;for(autoe:st)soldiers.push_back(e);// Initializing the result as ans=0intans=0;// colr[] to apply Bipartite coloringvector<int>colr(20001,-1);// Loop for each soldierfor(autoe:soldiers){// if already colored we continue;if(colr[e]!=-1)continue;// one and zero are our two colors.one=0;zero=0;// Applying Bipartite ColoringBipartiteColor(e,g,colr,0);// Updating our answerans+=max(one,zero);}if(flag)cout<<ans;elsecout<<-1;}// Driver Codeintmain(){// Input test caseintN=4;vector<vector<int>>arr={{1,2},{2,3},{2,4},{2,5}};// Function callmaximumSoldier(N,arr);return0;}
Java
//Java code for the above approachimportjava.util.*;publicclassGFG{// one and zero are our two colorsstaticintone,zero;// Flag to check whether the answer// exists or notstaticbooleanflag=true;staticvoidBipartiteColor(intv,List<List<Integer>>g,List<Integer>colr,intpaint){// if the vertex is already coloredif(colr.get(v)!=-1){// if previous color and current paint// contradict each other then our answer// won't existif(colr.get(v)!=paint)flag=false;return;}// paint the current vertex vcolr.set(v,paint);// if paint is 1if(paint==1)one++;// if paint is 0elsezero++;// Recursive calls on the child of vertex vfor(intchild:g.get(v)){// Giving the complementary color to the// child i.e. if colr[v]=1 then// colr[child]=0 and vice versaBipartiteColor(child,g,colr,(paint==1)?0:1);}}staticvoidmaximumSoldier(intN,List<List<Integer>>arr){// Creating a graph// taking 20001 as the upper bound// for unique soldiers.List<List<Integer>>g=newArrayList<>();for(inti=0;i<20001;i++){g.add(newArrayList<>());}// set to store all the unique soldiersSet<Integer>st=newHashSet<>();for(inti=0;i<N;i++){// u and v stores the soldierintu,v;u=arr.get(i).get(0);v=arr.get(i).get(1);// Initializing the graphg.get(u).add(v);g.get(v).add(u);// Inserting u and v into setst.add(u);st.add(v);}// To store all the unique// soldiers of set stList<Integer>soldiers=newArrayList<>(st);// Initializing the result as ans=0intans=0;// colr[] to apply Bipartite coloringList<Integer>colr=newArrayList<>(Collections.nCopies(20001,-1));// Loop for each soldierfor(inte:soldiers){// if already colored we continue;if(colr.get(e)!=-1)continue;// one and zero are our two colors.one=0;zero=0;// Applying Bipartite ColoringBipartiteColor(e,g,colr,0);// Updating our answerans+=Math.max(one,zero);}if(flag)System.out.println(ans);elseSystem.out.println(-1);}// Driver Codepublicstaticvoidmain(String[]args){// Input test caseintN=4;List<List<Integer>>arr=newArrayList<>();arr.add(Arrays.asList(1,2));arr.add(Arrays.asList(2,3));arr.add(Arrays.asList(2,4));arr.add(Arrays.asList(2,5));// Function callmaximumSoldier(N,arr);}}
Python3
# Python code for the above approach : # Function to perform Bipartite Coloringdefbipartite_color(v,g,colr,paint):globalone,zero,flag# If the vertex is already coloredifcolr[v]!=-1:# If the previous color and current paint# contradict each other, then our answer# won't existifcolr[v]!=paint:flag=Falsereturn# Paint the current vertex vcolr[v]=paint# If paint is 1ifpaint:one+=1# If paint is 0else:zero+=1# Recursive calls on the child of vertex vforchilding[v]:# Giving the complementary color to the# child, i.e., if colr[v]=1 then# colr[child]=0 and vice versabipartite_color(child,g,colr,notpaint)# Function to find the maximum number of soldiersdefmaximum_soldier(N,arr):globalone,zero,flag# Creating a graph with an upper bound of 20001g=[[]for_inrange(20001)]# Set to store all the unique soldiersst=set()foriinrange(N):# u and v store the soldieru,v=arr[i][0],arr[i][1]# Initializing the graphg[u].append(v)g[v].append(u)# Inserting u and v into the setst.add(u)st.add(v)# To store all the unique soldiers from the setsoldiers=list(st)# Initializing the result as ans=0ans=0# colr[] to apply Bipartite coloringcolr=[-1]*20001# Loop for each soldierforeinsoldiers:# If already colored, continueifcolr[e]!=-1:continue# one and zero are our two colorsone=0zero=0# Applying Bipartite Coloringbipartite_color(e,g,colr,0)# Updating our answerans+=max(one,zero)ifflag:print(ans)else:print(-1)if__name__=="__main__":# Input test caseN=4arr=[[1,2],[2,3],[2,4],[2,5]]flag=True# Function callmaximum_soldier(N,arr)# this code is contributed by uttamdp_10
C#
//Java code for the above approachusingSystem;usingSystem.Collections.Generic;usingSystem.Linq;classGFG{// one and zero are our two colorsstaticintone,zero;// Flag to check whether the answer// exists or notstaticboolflag=true;staticvoidBipartiteColor(intv,List<List<int>>g,List<int>colr,intpaint){// If the vertex is already coloredif(colr[v]!=-1){// If previous color and current paint// contradict each other then our answer// won't existif(colr[v]!=paint)flag=false;return;}// Paint the current vertex vcolr[v]=paint;// If paint is 1if(paint==1)one++;// If paint is 0elsezero++;// Recursive calls on the child of vertex vforeach(intchilding[v]){// Giving the complementary color to the// child, i.e. if colr[v] = 1 then// colr[child] = 0 and vice versaBipartiteColor(child,g,colr,(paint==1)?0:1);}}staticvoidMaximumSoldier(intN,List<List<int>>arr){// Creating a graph// taking 20001 as the upper bound// for unique soldiers.List<List<int>>g=newList<List<int>>();for(inti=0;i<20001;i++){g.Add(newList<int>());}// Set to store all the unique soldiersHashSet<int>st=newHashSet<int>();for(inti=0;i<N;i++){// u and v stores the soldierintu,v;u=arr[i][0];v=arr[i][1];// Initializing the graphg[u].Add(v);g[v].Add(u);// Inserting u and v into setst.Add(u);st.Add(v);}// To store all the unique// soldiers of set stList<int>soldiers=st.ToList();// Initializing the result as ans = 0intans=0;// colr[] to apply Bipartite coloringList<int>colr=Enumerable.Repeat(-1,20001).ToList();// Loop for each soldierforeach(inteinsoldiers){// if already colored we continue;if(colr[e]!=-1)continue;// one and zero are our two colors.one=0;zero=0;// Applying Bipartite ColoringBipartiteColor(e,g,colr,0);// Updating our answerans+=Math.Max(one,zero);}if(flag)Console.WriteLine(ans);elseConsole.WriteLine(-1);}// Driver CodepublicstaticvoidMain(string[]args){// Input test caseintN=4;List<List<int>>arr=newList<List<int>>{newList<int>{1,2},newList<int>{2,3},newList<int>{2,4},newList<int>{2,5}};// Function callMaximumSoldier(N,arr);}}
JavaScript
// Bipartite graph coloring variablesletone,zero;letflag=true;functionbipartiteColor(v,g,colr,paint){// If the vertex is already coloredif(colr[v]!==-1){// If previous color and current paint contradict each other// then our answer won't existif(colr[v]!==paint){flag=false;}return;}colr[v]=paint;if(paint===1){one++;}else{zero++;}for(constchildofg[v]){// Giving the complementary color to the child// If colr[v] = 1, then colr[child] = 0 and vice versabipartiteColor(child,g,colr,paint===1?0:1);}}functionmaximumSoldier(N,arr){// Creating a graphconstg=newArray(20001).fill(null).map(()=>[]);constst=newSet();for(leti=0;i<N;i++){// u and v store the soldiersconstu=arr[i][0];constv=arr[i][1];// Initializing the graphg[u].push(v);g[v].push(u);// Inserting u and v into the setst.add(u);st.add(v);}// Convert the set to an array of unique soldiersconstsoldiers=[...st];// Initialize the result as ans = 0letans=0;// Array colr[] to apply Bipartite coloringconstcolr=newArray(20001).fill(-1);// Loop for each soldierfor(consteofsoldiers){// If already colored, continueif(colr[e]!==-1){continue;}one=0;zero=0;// Applying Bipartite ColoringbipartiteColor(e,g,colr,0);// Updating the answerans+=Math.max(one,zero);}if(flag){console.log(ans);}else{console.log(-1);}}// Input test caseconstN=4;constarr=[[1,2],[2,3],[2,4],[2,5]];// Function callmaximumSoldier(N,arr);
Output
4
Time Complexity: O(N*logN + N*(V+E)), where N is the size of arr[], V is the unique number of soldiers(vertices) and E is the total edges in the graph.
Auxiliary Space: O(V), where V is the unique number of soldiers(vertices)