11from collections import defaultdict , deque
2+ from collections .abc import Hashable , Iterable , Mapping
23
34
4- def is_bipartite_dfs (graph : dict [ int , list [ int ]]) -> bool :
5+ def is_bipartite_dfs (graph : Mapping [ Hashable , Iterable [ Hashable ]]) -> bool :
56 """
67 Check if a graph is bipartite using depth-first search (DFS).
78
89 Args:
9- `graph`: Adjacency list representing the graph .
10+ `graph`: Mapping of nodes to their neighbors. Nodes must be hashable .
1011
1112 Returns:
1213 ``True`` if bipartite, ``False`` otherwise.
1314
1415 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+ vertices within the same set are connected by an edge. Neighbor nodes that do
17+ not appear as keys are treated as isolated nodes with no outgoing edges.
1618
1719 Examples:
1820
@@ -33,7 +35,6 @@ def is_bipartite_dfs(graph: dict[int, list[int]]) -> bool:
3335 >>> is_bipartite_dfs({7: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2], 4: [0]})
3436 False
3537
36- >>> # FIXME: This test should fails with KeyError: 4.
3738 >>> is_bipartite_dfs({0: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2], 9: [0]})
3839 False
3940 >>> is_bipartite_dfs({0: [-1, 3], 1: [0, -2]})
@@ -43,8 +44,6 @@ def is_bipartite_dfs(graph: dict[int, list[int]]) -> bool:
4344 >>> is_bipartite_dfs({0.9: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2]})
4445 True
4546
46- >>> # FIXME: This test should fails with
47- >>> # TypeError: list indices must be integers or...
4847 >>> is_bipartite_dfs({0: [1.0, 3.0], 1.0: [0, 2.0], 2.0: [1.0, 3.0], 3.0: [0, 2.0]})
4948 True
5049 >>> is_bipartite_dfs({"a": [1, 3], "b": [0, 2], "c": [1, 3], "d": [0, 2]})
@@ -53,7 +52,7 @@ def is_bipartite_dfs(graph: dict[int, list[int]]) -> bool:
5352 True
5453 """
5554
56- def depth_first_search (node : int , color : int ) -> bool :
55+ def depth_first_search (node : Hashable , color : int ) -> bool :
5756 """
5857 Perform Depth-First Search (DFS) on the graph starting from a node.
5958
@@ -74,25 +73,26 @@ def depth_first_search(node: int, color: int) -> bool:
7473 return False
7574 return visited [node ] == color
7675
77- visited : defaultdict [int , int ] = defaultdict (lambda : - 1 )
76+ visited : defaultdict [Hashable , int ] = defaultdict (lambda : - 1 )
7877 for node in graph :
7978 if visited [node ] == - 1 and not depth_first_search (node , 0 ):
8079 return False
8180 return True
8281
8382
84- def is_bipartite_bfs (graph : dict [ int , list [ int ]]) -> bool :
83+ def is_bipartite_bfs (graph : Mapping [ Hashable , Iterable [ Hashable ]]) -> bool :
8584 """
8685 Check if a graph is bipartite using a breadth-first search (BFS).
8786
8887 Args:
89- `graph`: Adjacency list representing the graph .
88+ `graph`: Mapping of nodes to their neighbors. Nodes must be hashable .
9089
9190 Returns:
9291 ``True`` if bipartite, ``False`` otherwise.
9392
9493 Check if the graph can be divided into two sets of vertices, such that no two
95- vertices within the same set are connected by an edge.
94+ vertices within the same set are connected by an edge. Neighbor nodes that do
95+ not appear as keys are treated as isolated nodes with no outgoing edges.
9696
9797 Examples:
9898
@@ -113,7 +113,6 @@ def is_bipartite_bfs(graph: dict[int, list[int]]) -> bool:
113113 >>> is_bipartite_bfs({7: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2], 4: [0]})
114114 False
115115
116- >>> # FIXME: This test should fails with KeyError: 4.
117116 >>> is_bipartite_bfs({0: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2], 9: [0]})
118117 False
119118 >>> is_bipartite_bfs({0: [-1, 3], 1: [0, -2]})
@@ -123,19 +122,17 @@ def is_bipartite_bfs(graph: dict[int, list[int]]) -> bool:
123122 >>> is_bipartite_bfs({0.9: [1, 3], 1: [0, 2], 2: [1, 3], 3: [0, 2]})
124123 True
125124
126- >>> # FIXME: This test should fails with
127- >>> # TypeError: list indices must be integers or...
128125 >>> is_bipartite_bfs({0: [1.0, 3.0], 1.0: [0, 2.0], 2.0: [1.0, 3.0], 3.0: [0, 2.0]})
129126 True
130127 >>> is_bipartite_bfs({"a": [1, 3], "b": [0, 2], "c": [1, 3], "d": [0, 2]})
131128 True
132129 >>> is_bipartite_bfs({0: ["b", "d"], 1: ["a", "c"], 2: ["b", "d"], 3: ["a", "c"]})
133130 True
134131 """
135- visited : defaultdict [int , int ] = defaultdict (lambda : - 1 )
132+ visited : defaultdict [Hashable , int ] = defaultdict (lambda : - 1 )
136133 for node in graph :
137134 if visited [node ] == - 1 :
138- queue : deque [int ] = deque ()
135+ queue : deque [Hashable ] = deque ()
139136 queue .append (node )
140137 visited [node ] = 0
141138 while queue :
0 commit comments