Skip to content

Commit 3f3c8cb

Browse files
modified: graphs/check_bipartite_graph_all.py
1 parent 118b3ff commit 3f3c8cb

File tree

1 file changed

+55
-90
lines changed

1 file changed

+55
-90
lines changed

Diff for: graphs/check_bipartite_graph_all.py

+55-90
Original file line numberDiff line numberDiff line change
@@ -1,122 +1,88 @@
1-
from collections import defaultdict
2-
from queue import Queue
1+
from collections import defaultdict, deque
32

4-
5-
def check_bipartite(graph: dict[int, list[int]]) -> bool:
3+
def is_bipartite_dfs(graph: defaultdict[int, list[int]]) -> bool:
64
"""
7-
Check if a graph is Bipartite using Depth-First Search.
5+
Check graph bipartite using DFS.
86
97
Args:
10-
graph: Adjacency list representing the graph.
8+
graph (defaultdict[int, list[int]]): Adjacency list.
119
1210
Returns:
13-
bool: True if no edge connects same set vertices.
11+
bool: True if bipartite, False otherwise.
12+
13+
Divides graph into two sets without same-set connections.
1414
1515
Examples:
16-
>>> is_bipartite(defaultdict(list, {0: [1, 2], 1: [0, 3], ...}))
17-
False
18-
>>> is_bipartite(defaultdict(list, {0: [1, 2], 1: [0, 2], 2: [0, 1]}))
19-
True
16+
>>> is_bipartite_dfs(defaultdict(list, {0: [1, 2], 1: [0, 3], 2: [0, 4]}))
17+
True
18+
>>> is_bipartite_dfs(defaultdict(list, {0: [1, 2], 1: [0, 2], 2: [0, 1]}))
19+
False
2020
"""
21-
queue: Queue = Queue()
22-
visited = [False] * len(graph)
23-
color = [-1] * len(graph)
24-
25-
def bfs() -> bool:
21+
def dfs(node, color):
2622
"""
27-
Perform Breadth-First Search (BFS) on a graph to check if it's bipartite.
23+
DFS starting from a node.
2824
2925
Args:
30-
graph (dict[int, list[int]]): An adjacency list representing the graph.
26+
node: Current node.
27+
color: Color assigned to the current node.
3128
3229
Returns:
33-
bool: True if there's no edge, False otherwise.
30+
bool: True if bipartite starting from the current node.
3431
3532
Examples:
36-
>>> bfs({0: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2]})
37-
True
38-
>>> bfs({0: [1, 2, 3], 1: [0, 2], 2: [0, 1, 3], 3: [0, 2]})
39-
False
33+
>>> dfs(0, 0, defaultdict(list, {0: [1, 2], 1: [0, 3], 2: [0, 4]}))
34+
True
35+
>>> dfs(0, 0, defaultdict(list, {0: [1, 2], 1: [0, 2], 2: [0, 1]}))
36+
False
4037
"""
41-
while not queue.empty():
42-
u = queue.get()
43-
visited[u] = True
44-
45-
for neighbour in graph[u]:
46-
if neighbour == u:
38+
if visited[node] == -1:
39+
visited[node] = color
40+
for neighbor in graph[node]:
41+
if not dfs(neighbor, 1 - color):
4742
return False
43+
return visited[node] == color
4844

49-
if color[neighbour] == -1:
50-
color[neighbour] = 1 - color[u]
51-
queue.put(neighbour)
52-
53-
elif color[neighbour] == color[u]:
54-
return False
55-
56-
return True
57-
58-
for i in range(len(graph)):
59-
if not visited[i]:
60-
queue.put(i)
61-
color[i] = 0
62-
if bfs() is False:
63-
return False
64-
45+
visited = defaultdict(lambda: -1)
46+
for node in graph:
47+
if visited[node] == -1 and not dfs(node, 0):
48+
return False
6549
return True
6650

67-
68-
if __name__ == "__main__":
69-
# Adjacency List of graph
70-
print(check_bipartite({0: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2]}))
71-
72-
73-
def is_bipartite(graph: defaultdict[int, list[int]]) -> bool:
51+
def is_bipartite_bfs(graph: defaultdict[int, list[int]]) -> bool:
7452
"""
75-
Check if a graph is Bipartite using Breadth-First Search.
53+
Check graph bipartite using BFS.
7654
7755
Args:
78-
graph: Adjacency list representing the graph.
56+
graph (defaultdict[int, list[int]]): Adjacency list.
7957
8058
Returns:
81-
bool: True if no edge connects same set vertices.
59+
bool: True if bipartite, False otherwise.
60+
61+
Divides graph into two sets without same-set connections.
8262
8363
Examples:
84-
>>> check_bipartite({0: [1, 3], 1: [0, 2], 2: [1, 3], ...})
85-
True
86-
>>> check_bipartite({0: [1, 2, 3], 1: [0, 2], ...})
87-
False
64+
>>> is_bipartite_bfs(defaultdict(list, {0: [1, 2], 1: [0, 3], 2: [0, 4]}))
65+
True
66+
>>> is_bipartite_bfs(defaultdict(list, {0: [1, 2], 1: [0, 2], 2: [0, 1]}))
67+
False
8868
"""
69+
visited = defaultdict(lambda: -1)
70+
for node in graph:
71+
if visited[node] == -1:
72+
queue = deque()
73+
queue.append(node)
74+
visited[node] = 0
75+
while queue:
76+
curr_node = queue.popleft()
77+
for neighbor in graph[curr_node]:
78+
if visited[neighbor] == -1:
79+
visited[neighbor] = 1 - visited[curr_node]
80+
queue.append(neighbor)
81+
elif visited[neighbor] == visited[curr_node]:
82+
return False
83+
return True
8984

90-
def dfs(node: int, color: int) -> bool:
91-
"""
92-
Perform depth-first search from a node with specified color.
93-
94-
Args:
95-
node (int): Current node being visited.
96-
color (int): Color assigned to the current node.
97-
98-
Returns:
99-
bool: True if the graph is bipartite fromcurrent node,else False.
100-
101-
Examples:
102-
>>> dfs(0, 0, defaultdict(list, {0: [1, 2], ...}))
103-
False
104-
>>> dfs(0, 0, defaultdict(list, {0: [1, 2], 1: [0, 2], ...}))
105-
True
106-
"""
107-
visited[node] = color
108-
return any(
109-
visited[neighbour] == color
110-
or (visited[neighbour] == -1 and not dfs(neighbour, 1 - color))
111-
for neighbour in graph[node]
112-
)
113-
114-
visited: defaultdict[int, int] = defaultdict(lambda: -1)
115-
116-
return all(not (visited[node] == -1 and not dfs(node, 0)) for node in graph)
117-
118-
119-
if __name__ == "__main__":
85+
if __name__ == "__main":
12086
import doctest
12187

12288
result = doctest.testmod()
@@ -125,4 +91,3 @@ def dfs(node: int, color: int) -> bool:
12591
print(f"{result.failed} test(s) failed.")
12692
else:
12793
print("All tests passed!")
128-

0 commit comments

Comments
 (0)