检查图是否为二分图,并添加每个新边

时间:2018-07-19 11:07:21

标签: algorithm data-structures graph

给出图形中边的多个输入,例如(第一行是连接数):

<plugin>
    <groupId>org.jvnet.jaxb2.maven2</groupId>
    <artifactId>maven-jaxb2-plugin</artifactId>
    <version>${jaxb2.maven.version}</version>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <bindings>
            <binding>
                <fileset>
                    <directory>${basedir}/src/main/resources</directory>
                    <includes>
                        <include>binding.xml</include>
                    </includes>
                </fileset>
            </binding>
        </bindings>
    <configuration>
</plugin>

我必须检查在每次输入后该图是否仍然是二部图,如果图是非二部图,我们将中断。 我认为这是一个图形着色问题,但是我无法实现,请提供一些算法来帮助我。

1 个答案:

答案 0 :(得分:3)

该图是二分图,前提是您可以找到该图的两种颜色。这很容易实现,因为不涉及回溯。对于每个成功节点,只有一种颜色可用,并且如果不可能使用该颜色,因为相邻的一个已经具有该颜色,则该图不是二分图。

例如,您可以将此作为深度优先搜索来实现,分别跟踪颜色A和颜色B的两个节点集。每次展开新节点时,都将切换颜色,如果该节点应被着色为A,但已经在B集中,则该图不是二分图。

但是,您的情况似乎有些不同,在添加每个单独的边后检查图是否为二分图。您仍然可以在每次迭代中在整个图形上运行DFS,但这可能太慢了。

相反,请为每个(仍然)断开的子图跟踪两组具有颜色A和颜色B的节点。因此,当您添加边缘(x, y)时:

  • 检查子图xy所属(使用某种地图/词典)
  • 如果都不属于子图,则开始一个新的子图
  • 如果一个属于子图,但另一个不在图中,则给另一个节点与已经包含的节点相反的颜色
  • 如果两个都属于不同的子图,则将子图合并为一个(合并颜色集);这可能需要翻转其中一张图的颜色,以使xy的颜色不同;确保更新地图,使所有这些节点都指向合并的图
  • 如果两者都属于同一子图,则它们必须使用不同的颜色集,否则该图不是二分图的

在您的情况下,子图映射可能在每个边之后看起来像这样:

1 2 -> {1: ({1}, {2}), 2: (see 1)}
2 3 -> {1: ({1, 3}, {2}), 2: (see 1), 3: (see 1)}
5 6 -> {1: ({1, 3}, {2}), 2: (see 1), 3: (see 1), 5: ({5}, {6}), 6: (see 5)}
1 5 -> {1: ({1, 3, 6}, {2, 5}), 2: (see 1), 3: (see 1), 5: (see 1), 6: (see 1)}