为什么我们不能使用简单迭代来确定图是否为二部图?

huangapple go评论60阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2023年3月21日 01:46:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/75793615.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定