Skip to content

Commit 99681ef

Browse files
fixes#8098
1 parent 3f3c8cb commit 99681ef

File tree

2 files changed

+66
-146
lines changed

2 files changed

+66
-146
lines changed

Diff for: graphs/check_bipartite_graph_all.py

+66-58
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,101 @@
1-
from collections import defaultdict, deque
1+
from queue import Queue
2+
from collections import defaultdict
23

3-
def is_bipartite_dfs(graph: defaultdict[int, list[int]]) -> bool:
4+
def check_bipartite(graph: dict[int, list[int]])->bool:
45
"""
5-
Check graph bipartite using DFS.
6+
Check graph bipartite using BFS.
67
78
Args:
8-
graph (defaultdict[int, list[int]]): Adjacency list.
9+
graph (dict[int, List[int]]): Adjacency list.
910
1011
Returns:
1112
bool: True if bipartite, False otherwise.
1213
1314
Divides graph into two sets without same-set connections.
1415
1516
Examples:
16-
>>> is_bipartite_dfs(defaultdict(list, {0: [1, 2], 1: [0, 3], 2: [0, 4]}))
17+
>>> check_bipartite(dict(list, {0: [1, 2], 1: [0, 3], 2: [0, 4]}))
1718
True
18-
>>> is_bipartite_dfs(defaultdict(list, {0: [1, 2], 1: [0, 2], 2: [0, 1]}))
19+
>>> check_bipartite(dict(list, {0: [1, 2], 1: [0, 2], 2: [0, 1]}))
1920
False
2021
"""
21-
def dfs(node, color):
22-
"""
23-
DFS starting from a node.
24-
25-
Args:
26-
node: Current node.
27-
color: Color assigned to the current node.
22+
queue:Queue() = Queue()
23+
visited = [False] * len(graph)
24+
color = [-1] * len(graph)
2825

29-
Returns:
30-
bool: True if bipartite starting from the current node.
26+
def bfs()->bool:
27+
while not queue.empty():
28+
u = queue.get()
29+
visited[u] = True
3130

32-
Examples:
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
37-
"""
38-
if visited[node] == -1:
39-
visited[node] = color
40-
for neighbor in graph[node]:
41-
if not dfs(neighbor, 1 - color):
31+
for neighbour in graph[u]:
32+
if neighbour == u:
4233
return False
43-
return visited[node] == color
4434

45-
visited = defaultdict(lambda: -1)
46-
for node in graph:
47-
if visited[node] == -1 and not dfs(node, 0):
48-
return False
49-
return True
35+
if color[neighbour] == -1:
36+
color[neighbour] = 1 - color[u]
37+
queue.put(neighbour)
5038

51-
def is_bipartite_bfs(graph: defaultdict[int, list[int]]) -> bool:
39+
elif color[neighbour] == color[u]:
40+
return False
41+
return True
42+
43+
for i in range(len(graph)):
44+
if not visited[i]:
45+
queue.put(i)
46+
color[i] = 0
47+
if bfs() is False:
48+
return False
49+
return True
50+
def is_bipartite(graph: defaultdict[int, list[int]]) -> bool:
5251
"""
53-
Check graph bipartite using BFS.
52+
Check whether a graph is Bipartite or not using Depth-First Search (DFS).
53+
54+
A Bipartite Graph is a graph whose vertices can be divided into two independent
55+
sets, U and V such that every edge (u, v) either connects a vertex from
56+
U to V or a vertex from V to U. In other words, for every edge (u, v),
57+
either u belongs to U and v to V, or u belongs to V and v to U. There is
58+
no edge that connects vertices of the same set.
5459
5560
Args:
56-
graph (defaultdict[int, list[int]]): Adjacency list.
61+
graph: An adjacency list representing the graph.
5762
5863
Returns:
59-
bool: True if bipartite, False otherwise.
60-
61-
Divides graph into two sets without same-set connections.
64+
True if there's no edge that connects vertices of the same set, False otherwise.
6265
6366
Examples:
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
67+
>>> is_bipartite(
68+
... defaultdict(list, {0: [1, 2], 1: [0, 3], 2: [0, 4], 3: [1], 4: [2]})
69+
... )
70+
False
71+
>>> is_bipartite(defaultdict(list, {0: [1, 2], 1: [0, 2], 2: [0, 1]}))
72+
True
6873
"""
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
8474

85-
if __name__ == "__main":
75+
def depth_first_search(node: int, color: int) -> bool:
76+
visited[node] = color
77+
return any(
78+
visited[neighbour] == color
79+
or (
80+
visited[neighbour] == -1
81+
and not depth_first_search(neighbour, 1 - color)
82+
)
83+
for neighbour in graph[node]
84+
)
85+
86+
visited: defaultdict[int, int] = defaultdict(lambda: -1)
87+
88+
return all(
89+
not (visited[node] == -1 and not depth_first_search(node, 0)) for node in graph
90+
)
91+
92+
93+
if __name__ == "__main__":
8694
import doctest
8795

8896
result = doctest.testmod()
8997

9098
if result.failed:
9199
print(f"{result.failed} test(s) failed.")
92100
else:
93-
print("All tests passed!")
101+
print("All tests passed!")

Diff for: graphs/check_bipatrite.py

-88
This file was deleted.

0 commit comments

Comments
 (0)