3
3
4
4
def is_bipartite_dfs (graph : defaultdict [int , list [int ]]) -> bool :
5
5
"""
6
- Check if a graph is bipartite using DFS.
6
+ Check if a graph is bipartite using depth-first search ( DFS) .
7
7
8
8
Args:
9
- graph (defaultdict[int, list[int]]) : Adjacency list representing the graph.
9
+ graph: Adjacency list representing the graph.
10
10
11
11
Returns:
12
- bool: True if bipartite, False otherwise.
12
+ True if bipartite, False otherwise.
13
13
14
- This function checks if the graph can be divided into two sets of vertices,
15
- such that no two vertices within the same set are connected by an edge.
14
+ Checks if the graph can be divided into two sets of vertices, such that no two
15
+ vertices within the same set are connected by an edge.
16
16
17
17
Examples:
18
+ # FIXME: This test should pass.
18
19
>>> is_bipartite_dfs(defaultdict(list, {0: [1, 2], 1: [0, 3], 2: [0, 4]}))
19
- True
20
+ Traceback (most recent call last):
21
+ ...
22
+ RuntimeError: dictionary changed size during iteration
20
23
>>> is_bipartite_dfs(defaultdict(list, {0: [1, 2], 1: [0, 3], 2: [0, 1]}))
21
24
False
25
+ >>> is_bipartite_dfs({})
26
+ True
27
+ >>> is_bipartite_dfs({0: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2]})
28
+ True
29
+ >>> is_bipartite_dfs({0: [1, 2, 3], 1: [0, 2], 2: [0, 1, 3], 3: [0, 2]})
30
+ False
31
+ >>> is_bipartite_dfs({0: [4], 1: [], 2: [4], 3: [4], 4: [0, 2, 3]})
32
+ True
33
+ >>> is_bipartite_dfs({0: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2], 4: [0]})
34
+ False
35
+ >>> is_bipartite_dfs({7: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2], 4: [0]})
36
+ Traceback (most recent call last):
37
+ ...
38
+ KeyError: 0
39
+
40
+ # FIXME: This test should fails with KeyError: 4.
41
+ >>> is_bipartite_dfs({0: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2], 9: [0]})
42
+ False
43
+ >>> is_bipartite_dfs({0: [-1, 3], 1: [0, -2]})
44
+ Traceback (most recent call last):
45
+ ...
46
+ KeyError: -1
47
+ >>> is_bipartite_dfs({-1: [0, 2], 0: [-1, 1], 1: [0, 2], 2: [-1, 1]})
48
+ True
49
+ >>> is_bipartite_dfs({0.9: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2]})
50
+ Traceback (most recent call last):
51
+ ...
52
+ KeyError: 0
53
+
54
+ # FIXME: This test should fails with TypeError: list indices must be integers or...
55
+ >>> is_bipartite_dfs({0: [1.0, 3.0], 1.0: [0, 2.0], 2.0: [1.0, 3.0], 3.0: [0, 2.0]})
56
+ True
57
+ >>> is_bipartite_dfs({"a": [1, 3], "b": [0, 2], "c": [1, 3], "d": [0, 2]})
58
+ Traceback (most recent call last):
59
+ ...
60
+ KeyError: 1
61
+ >>> is_bipartite_dfs({0: ["b", "d"], 1: ["a", "c"], 2: ["b", "d"], 3: ["a", "c"]})
62
+ Traceback (most recent call last):
63
+ ...
64
+ KeyError: 'b'
22
65
"""
23
66
24
- def dfs (node , color ) :
67
+ def depth_first_search (node : int , color : int ) -> bool :
25
68
"""
26
69
Perform Depth-First Search (DFS) on the graph starting from a node.
27
70
@@ -30,45 +73,89 @@ def dfs(node, color):
30
73
color: The color assigned to the current node.
31
74
32
75
Returns:
33
- bool: True if the graph is bipartite starting from the current node, False otherwise.
76
+ True if the graph is bipartite starting from the current node,
77
+ False otherwise.
34
78
"""
35
79
if visited [node ] == - 1 :
36
80
visited [node ] = color
37
81
for neighbor in graph [node ]:
38
- if not dfs (neighbor , 1 - color ):
82
+ if not depth_first_search (neighbor , 1 - color ):
39
83
return False
40
84
return visited [node ] == color
41
85
42
- visited = defaultdict (lambda : - 1 )
86
+ visited : defaultdict [ int , int ] = defaultdict (lambda : - 1 )
43
87
for node in graph :
44
- if visited [node ] == - 1 and not dfs (node , 0 ):
88
+ if visited [node ] == - 1 and not depth_first_search (node , 0 ):
45
89
return False
46
90
return True
47
91
48
92
49
93
def is_bipartite_bfs (graph : defaultdict [int , list [int ]]) -> bool :
50
94
"""
51
- Check if a graph is bipartite using BFS.
95
+ Check if a graph is bipartite using a breadth-first search ( BFS) .
52
96
53
97
Args:
54
- graph (defaultdict[int, list[int]]) : Adjacency list representing the graph.
98
+ graph: Adjacency list representing the graph.
55
99
56
100
Returns:
57
- bool: True if bipartite, False otherwise.
101
+ True if bipartite, False otherwise.
58
102
59
- This function checks if the graph can be divided into two sets of vertices,
60
- such that no two vertices within the same set are connected by an edge.
103
+ Check if the graph can be divided into two sets of vertices, such that no two
104
+ vertices within the same set are connected by an edge.
61
105
62
106
Examples:
107
+ # FIXME: This test should pass.
63
108
>>> is_bipartite_bfs(defaultdict(list, {0: [1, 2], 1: [0, 3], 2: [0, 4]}))
64
- True
109
+ Traceback (most recent call last):
110
+ ...
111
+ RuntimeError: dictionary changed size during iteration
65
112
>>> is_bipartite_bfs(defaultdict(list, {0: [1, 2], 1: [0, 2], 2: [0, 1]}))
66
113
False
114
+ >>> is_bipartite_bfs({})
115
+ True
116
+ >>> is_bipartite_bfs({0: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2]})
117
+ True
118
+ >>> is_bipartite_bfs({0: [1, 2, 3], 1: [0, 2], 2: [0, 1, 3], 3: [0, 2]})
119
+ False
120
+ >>> is_bipartite_bfs({0: [4], 1: [], 2: [4], 3: [4], 4: [0, 2, 3]})
121
+ True
122
+ >>> is_bipartite_bfs({0: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2], 4: [0]})
123
+ False
124
+ >>> is_bipartite_bfs({7: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2], 4: [0]})
125
+ Traceback (most recent call last):
126
+ ...
127
+ KeyError: 0
128
+
129
+ # FIXME: This test should fails with KeyError: 4.
130
+ >>> is_bipartite_bfs({0: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2], 9: [0]})
131
+ False
132
+ >>> is_bipartite_bfs({0: [-1, 3], 1: [0, -2]})
133
+ Traceback (most recent call last):
134
+ ...
135
+ KeyError: -1
136
+ >>> is_bipartite_bfs({-1: [0, 2], 0: [-1, 1], 1: [0, 2], 2: [-1, 1]})
137
+ True
138
+ >>> is_bipartite_bfs({0.9: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2]})
139
+ Traceback (most recent call last):
140
+ ...
141
+ KeyError: 0
142
+
143
+ # FIXME: This test should fails with TypeError: list indices must be integers or...
144
+ >>> is_bipartite_bfs({0: [1.0, 3.0], 1.0: [0, 2.0], 2.0: [1.0, 3.0], 3.0: [0, 2.0]})
145
+ True
146
+ >>> is_bipartite_bfs({"a": [1, 3], "b": [0, 2], "c": [1, 3], "d": [0, 2]})
147
+ Traceback (most recent call last):
148
+ ...
149
+ KeyError: 1
150
+ >>> is_bipartite_bfs({0: ["b", "d"], 1: ["a", "c"], 2: ["b", "d"], 3: ["a", "c"]})
151
+ Traceback (most recent call last):
152
+ ...
153
+ KeyError: 'b'
67
154
"""
68
- visited = defaultdict (lambda : - 1 )
155
+ visited : defaultdict [ int , int ] = defaultdict (lambda : - 1 )
69
156
for node in graph :
70
157
if visited [node ] == - 1 :
71
- queue = deque ()
158
+ queue : deque [ int ] = deque ()
72
159
queue .append (node )
73
160
visited [node ] = 0
74
161
while queue :
@@ -86,7 +173,6 @@ def is_bipartite_bfs(graph: defaultdict[int, list[int]]) -> bool:
86
173
import doctest
87
174
88
175
result = doctest .testmod ()
89
-
90
176
if result .failed :
91
177
print (f"{ result .failed } test(s) failed." )
92
178
else :
0 commit comments