1
1
from collections import defaultdict , deque
2
2
3
3
4
- def is_bipartite_dfs (graph : defaultdict [int , list [int ]]) -> bool :
4
+ def is_bipartite_dfs (graph : dict [int , list [int ]]) -> bool :
5
5
"""
6
6
Check if a graph is bipartite using depth-first search (DFS).
7
7
@@ -16,12 +16,9 @@ def is_bipartite_dfs(graph: defaultdict[int, list[int]]) -> bool:
16
16
17
17
Examples:
18
18
19
- >>> # FIXME: This test should pass.
20
- >>> is_bipartite_dfs(defaultdict(list, {0: [1, 2], 1: [0, 3], 2: [0, 4]}))
21
- Traceback (most recent call last):
22
- ...
23
- RuntimeError: dictionary changed size during iteration
24
- >>> is_bipartite_dfs(defaultdict(list, {0: [1, 2], 1: [0, 3], 2: [0, 1]}))
19
+ >>> is_bipartite_dfs({0: [1, 2], 1: [0, 3], 2: [0, 4]})
20
+ True
21
+ >>> is_bipartite_dfs({0: [1, 2], 1: [0, 3], 2: [0, 1]})
25
22
False
26
23
>>> is_bipartite_dfs({})
27
24
True
@@ -34,36 +31,26 @@ def is_bipartite_dfs(graph: defaultdict[int, list[int]]) -> bool:
34
31
>>> is_bipartite_dfs({0: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2], 4: [0]})
35
32
False
36
33
>>> is_bipartite_dfs({7: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2], 4: [0]})
37
- Traceback (most recent call last):
38
- ...
39
- KeyError: 0
34
+ False
40
35
41
36
>>> # FIXME: This test should fails with KeyError: 4.
42
37
>>> is_bipartite_dfs({0: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2], 9: [0]})
43
38
False
44
39
>>> is_bipartite_dfs({0: [-1, 3], 1: [0, -2]})
45
- Traceback (most recent call last):
46
- ...
47
- KeyError: -1
40
+ False
48
41
>>> is_bipartite_dfs({-1: [0, 2], 0: [-1, 1], 1: [0, 2], 2: [-1, 1]})
49
42
True
50
43
>>> is_bipartite_dfs({0.9: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2]})
51
- Traceback (most recent call last):
52
- ...
53
- KeyError: 0
44
+ True
54
45
55
46
>>> # FIXME: This test should fails with
56
47
>>> # TypeError: list indices must be integers or...
57
48
>>> is_bipartite_dfs({0: [1.0, 3.0], 1.0: [0, 2.0], 2.0: [1.0, 3.0], 3.0: [0, 2.0]})
58
49
True
59
50
>>> is_bipartite_dfs({"a": [1, 3], "b": [0, 2], "c": [1, 3], "d": [0, 2]})
60
- Traceback (most recent call last):
61
- ...
62
- KeyError: 1
51
+ True
63
52
>>> is_bipartite_dfs({0: ["b", "d"], 1: ["a", "c"], 2: ["b", "d"], 3: ["a", "c"]})
64
- Traceback (most recent call last):
65
- ...
66
- KeyError: 'b'
53
+ True
67
54
"""
68
55
69
56
def depth_first_search (node : int , color : int ) -> bool :
@@ -80,6 +67,8 @@ def depth_first_search(node: int, color: int) -> bool:
80
67
"""
81
68
if visited [node ] == - 1 :
82
69
visited [node ] = color
70
+ if node not in graph :
71
+ return True
83
72
for neighbor in graph [node ]:
84
73
if not depth_first_search (neighbor , 1 - color ):
85
74
return False
@@ -92,7 +81,7 @@ def depth_first_search(node: int, color: int) -> bool:
92
81
return True
93
82
94
83
95
- def is_bipartite_bfs (graph : defaultdict [int , list [int ]]) -> bool :
84
+ def is_bipartite_bfs (graph : dict [int , list [int ]]) -> bool :
96
85
"""
97
86
Check if a graph is bipartite using a breadth-first search (BFS).
98
87
@@ -107,12 +96,9 @@ def is_bipartite_bfs(graph: defaultdict[int, list[int]]) -> bool:
107
96
108
97
Examples:
109
98
110
- >>> # FIXME: This test should pass.
111
- >>> is_bipartite_bfs(defaultdict(list, {0: [1, 2], 1: [0, 3], 2: [0, 4]}))
112
- Traceback (most recent call last):
113
- ...
114
- RuntimeError: dictionary changed size during iteration
115
- >>> is_bipartite_bfs(defaultdict(list, {0: [1, 2], 1: [0, 2], 2: [0, 1]}))
99
+ >>> is_bipartite_bfs({0: [1, 2], 1: [0, 3], 2: [0, 4]})
100
+ True
101
+ >>> is_bipartite_bfs({0: [1, 2], 1: [0, 2], 2: [0, 1]})
116
102
False
117
103
>>> is_bipartite_bfs({})
118
104
True
@@ -125,36 +111,26 @@ def is_bipartite_bfs(graph: defaultdict[int, list[int]]) -> bool:
125
111
>>> is_bipartite_bfs({0: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2], 4: [0]})
126
112
False
127
113
>>> is_bipartite_bfs({7: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2], 4: [0]})
128
- Traceback (most recent call last):
129
- ...
130
- KeyError: 0
114
+ False
131
115
132
116
>>> # FIXME: This test should fails with KeyError: 4.
133
117
>>> is_bipartite_bfs({0: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2], 9: [0]})
134
118
False
135
119
>>> is_bipartite_bfs({0: [-1, 3], 1: [0, -2]})
136
- Traceback (most recent call last):
137
- ...
138
- KeyError: -1
120
+ False
139
121
>>> is_bipartite_bfs({-1: [0, 2], 0: [-1, 1], 1: [0, 2], 2: [-1, 1]})
140
122
True
141
123
>>> is_bipartite_bfs({0.9: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2]})
142
- Traceback (most recent call last):
143
- ...
144
- KeyError: 0
124
+ True
145
125
146
126
>>> # FIXME: This test should fails with
147
127
>>> # TypeError: list indices must be integers or...
148
128
>>> is_bipartite_bfs({0: [1.0, 3.0], 1.0: [0, 2.0], 2.0: [1.0, 3.0], 3.0: [0, 2.0]})
149
129
True
150
130
>>> is_bipartite_bfs({"a": [1, 3], "b": [0, 2], "c": [1, 3], "d": [0, 2]})
151
- Traceback (most recent call last):
152
- ...
153
- KeyError: 1
131
+ True
154
132
>>> is_bipartite_bfs({0: ["b", "d"], 1: ["a", "c"], 2: ["b", "d"], 3: ["a", "c"]})
155
- Traceback (most recent call last):
156
- ...
157
- KeyError: 'b'
133
+ True
158
134
"""
159
135
visited : defaultdict [int , int ] = defaultdict (lambda : - 1 )
160
136
for node in graph :
@@ -164,6 +140,8 @@ def is_bipartite_bfs(graph: defaultdict[int, list[int]]) -> bool:
164
140
visited [node ] = 0
165
141
while queue :
166
142
curr_node = queue .popleft ()
143
+ if curr_node not in graph :
144
+ continue
167
145
for neighbor in graph [curr_node ]:
168
146
if visited [neighbor ] == - 1 :
169
147
visited [neighbor ] = 1 - visited [curr_node ]
@@ -173,7 +151,7 @@ def is_bipartite_bfs(graph: defaultdict[int, list[int]]) -> bool:
173
151
return True
174
152
175
153
176
- if __name__ == "__main " :
154
+ if __name__ == "__main__ " :
177
155
import doctest
178
156
179
157
result = doctest .testmod ()
0 commit comments