英文:
Why can't we determine if a graph is bipartite with simple iteration?
问题
这是我要翻译的部分:
This is solvable via BFS fairly trivially in Python:
def possibleBipartition(self, n: int, dislikes: List[List[int]]) -> bool:
graph = defaultdict(set)
for a, b in dislikes:
graph[a-1].add(b-1)
graph[b-1].add(a-1)
q = deque({0})
colors = [None]*n
for i in range(n):
if colors[i] is None:
q = deque({i})
colors[i] = 0
while q:
cur = q.popleft()
for d in graph[cur]:
if colors[d] is None:
q.append(d)
colors[d] = 1 - colors[cur]
elif colors[d] == colors[cur]:
return False
return True
However, when I try to do it in linear time with simple iteration, the algorithm fails
def possibleBipartition(self, n: int, dislikes: List[List[int]]) -> bool:
graph = defaultdict(set)
for a, b in dislikes:
graph[a].add(b)
graph[b].add(a)
colors = {
0: set(),
1: set()
}
for i in range(n):
if i in colors[0]:
colors[1].update(graph[i])
elif i in colors[1]:
colors[0].update(graph[i])
else:
colors[0].add(i)
colors[1].update(graph[i])
return not (colors[0] & colors[1])
Why doesn't the second algorithm work and is there a way to solve this problem without some type of BFS/DFS/Union Find? I don't understand why the "recursive" algorithm is necessary. Why do we need to re-check old nodes rather than just comparing the sets?
英文:
This is the problem I'm trying to solve
> We want to split a group of n people (labeled from 1 to n) into two groups of any size. Each person may dislike some other people, and they should not go into the same group.
Given the integer n and the array dislikes where dislikes[i] = [ai, bi] indicates that the person labeled ai does not like the person labeled bi, return true if it is possible to split everyone into two groups in this way.
This is solvable via BFS fairly trivially in Python:
def possibleBipartition(self, n: int, dislikes: List[List[int]]) -> bool:
graph = defaultdict(set)
for a, b in dislikes:
graph[a-1].add(b-1)
graph[b-1].add(a-1)
q = deque({0})
colors = [None]*n
for i in range(n):
if colors[i] is None:
q = deque({i})
colors[i] = 0
while q:
cur = q.popleft()
for d in graph[cur]:
if colors[d] is None:
q.append(d)
colors[d] = 1 - colors[cur]
elif colors[d] == colors[cur]:
return False
return True
However, when I try to do it in linear time with simple iteration, the algorithm fails
def possibleBipartition(self, n: int, dislikes: List[List[int]]) -> bool:
graph = defaultdict(set)
for a, b in dislikes:
graph[a].add(b)
graph[b].add(a)
colors = {
0: set(),
1: set()
}
for i in range(n):
if i in colors[0]:
colors[1].update(graph[i])
elif i in colors[1]:
colors[0].update(graph[i])
else:
colors[0].add(i)
colors[1].update(graph[i])
return not (colors[0] & colors[1])
Why doesn't the second algorithm work and is there a way to solve this problem without some type of BFS/DFS/Union Find? I don't understand why the "recursive" algorithm is necessary. Why do we need to re-check old nodes rather than just comparing the sets?
答案1
得分: 5
你的算法假设,如果它不知道节点需要什么颜色,那么该节点可以是任何颜色。然而,这个假设是错误的。与广度优先搜索不同,广度优先搜索会强制对访问节点连接的所有节点进行着色,而你的代码只会强制对节点的直接邻居节点进行着色,这不足以避免冲突的颜色分配。
英文:
Say this is your graph:
0 - 3 - 2 - 1
and you visit node 0 first, then 1. Your algorithm paints nodes 0 and 1 the same color, but those nodes need to be opposite colors.
Your algorithm assumes that if it doesn't already know what color a node needs to be, the node can be any color. That assumption is wrong, though. Unlike the breadth-first search, which forces the colors of all nodes connected to a node it visits, your code only forces the colors of a node's immediate neighbors, which isn't enough to avoid conflicting color assignments.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论