Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to separate persons where no enemies can stay in same group in Python
Suppose we have a number n and a 2D matrix called enemies. Here n indicates there are n people labeled from [0, n - 1]. Now each row in enemies contains [a, b] which means that a and b are enemies. We have to check whether it is possible to partition the n people into two groups such that no two people that are enemies are in the same group.
So, if the input is like n = 4, enemies = [[0, 3],[3, 2]], then the output will be True, as we can have these two groups [0, 1] and [2, 3].
Approach
This problem can be solved using graph coloring. We treat each person as a node and enemy relationships as edges. If we can color the graph with 2 colors such that no adjacent nodes have the same color, then we can separate people into two groups.
To solve this, we will follow these steps ?
- Create an adjacency list to represent the enemy relationships
- Use DFS to attempt 2-coloring of the graph
- If we can color all nodes without conflicts, return True
Algorithm Steps
- graph := an empty adjacency list
- for each enemy pair(u, v) in enemies, do
- insert v at the end of graph[u]
- insert u at the end of graph[v]
- color := a new map to store node colors
- Define a function dfs() that takes u, c := 0 initially
- if u is already colored, check if current color matches expected color
- color[u] := c
- recursively color all neighbors with opposite color (c XOR 1)
- return true when all disconnected components can be 2-colored
Implementation
from collections import defaultdict
class Solution:
def solve(self, n, enemies):
# Build adjacency list graph
graph = defaultdict(list)
for u, v in enemies:
graph[u].append(v)
graph[v].append(u)
color = {}
def dfs(u, c=0):
# If already colored, check if color matches
if u in color:
return color[u] == c
# Color current node
color[u] = c
# Try to color all neighbors with opposite color
return all(dfs(v, c ^ 1) for v in graph[u])
# Check all disconnected components
return all(dfs(u) for u in range(n) if u not in color)
# Test the solution
solution = Solution()
n = 4
enemies = [[0, 3], [3, 2]]
result = solution.solve(n, enemies)
print(f"Can separate {n} people into two groups: {result}")
Can separate 4 people into two groups: True
Example Walkthrough
For n = 4, enemies = [[0, 3], [3, 2]] ?
# Step by step visualization
n = 4
enemies = [[0, 3], [3, 2]]
# Graph representation:
# 0 -- 3 -- 2
# 1 (isolated)
# Possible grouping:
group1 = [0, 2] # Color 0
group2 = [1, 3] # Color 1
print("Group 1 (Color 0):", group1)
print("Group 2 (Color 1):", group2)
print("No enemies in same group:", True)
Group 1 (Color 0): [0, 2] Group 2 (Color 1): [1, 3] No enemies in same group: True
How It Works
The algorithm uses DFS-based graph coloring ?
- Graph Construction: Enemy relationships form edges between nodes
- 2-Coloring: We attempt to color the graph with exactly 2 colors
- Conflict Detection: If any two adjacent nodes have the same color, separation is impossible
- Disconnected Components: Handle isolated nodes that have no enemies
Time and Space Complexity
- Time Complexity: O(V + E) where V is number of people and E is number of enemy pairs
- Space Complexity: O(V + E) for the adjacency list and color mapping
Conclusion
This problem is essentially a bipartite graph check using 2-coloring. The DFS approach efficiently determines if people can be separated into two groups where no enemies share the same group.
