如何从其他集创建不同的集?

时间:2012-09-01 06:41:00

标签: algorithm set distinct combinatorics

在解决Techgig.com上的问题时,我遇到了一个问题。问题是这样的:

  

一家公司在一年内为员工组织两次旅行。他们要   了解是否可以在旅行中发送所有员工。该   条件就像,没有员工可以去旅行。也来   确定哪个员工可以一起去约束就是那个   过去一起工作的员工不会属于同一组。   问题的例子:

     

假设工作历史如下:{(1,2),(2,3),(3,4)};   然后可以在两次旅行中容纳所有四名员工   (一名员工由1名和3名员工组成,另一名员工由员工2和1组成。   4)。同一行程中的两名员工都没有一起工作   在过去。假设工作历史为{(1,2),(1,3),(2,3)}   没有办法让两次旅行满足公司规则   并容纳所有员工。

有谁能告诉我如何处理这个问题?

我正在使用此代码进行DFS并为顶点着色。

static boolean DFS(int rootNode) {
        Stack<Integer> s = new Stack<Integer>();
        s.push(rootNode);
        state[rootNode] = true;
        color[rootNode] = 1;
        while (!s.isEmpty()) {
            int u = s.peek();
            for (int child = 0; child < numofemployees; child++) {
                if (adjmatrix[u][child] == 1) {
                    if (!state[child]) {
                        state[child] = true;
                        s.push(child);
                        color[child] = color[u] == 1 ? 2 : 1;
                        break;
                    } else {
                        s.pop();
                        if (color[u] == color[child])
                            return false;
                    }    

                }
            }
        }
        return true;
    }

2 个答案:

答案 0 :(得分:4)

此问题在功能上等同于测试无向图是否为bipartite。二分图是一个图,其中所有节点可以分布在两个集合中,并且在每个集合中,没有节点与另一个节点相邻。

要解决此问题,请执行以下步骤。

  1. 使用邻接对,构造无向图。这非常简单:每个数字代表一个节点,对于您给出的每一对,在这些节点之间形成连接。
  2. 测试新生成的图表的二分性。这可以在线性时间as described here实现。
  3. 如果图表是二分图并且您已经生成了两个节点集,则问题的答案是肯定的,并且每个节点集及其节点(员工)对应于两个节点集中的一个。
  4. 关于如何测试二分性的摘录:

      

    可以测试图表是否为二分图并返回   要么是双色(如果是二分),要么是奇数周期(如果是   在线性时间内,使用深度优先搜索。主要想法是   为每个顶点分配与其颜色不同的颜色   深度优先搜索树中的父级,按预订顺序分配颜色   遍历深度优先搜索树。这必然   提供由边缘组成的生成树的双色   将顶点连接到它们的父节点,但它可能没有正确的颜色   一些非树边缘。在深度优先搜索树中,其中一个   每个非树边的两个端点是另一个的祖先   端点,当深度优先搜索发现此边缘时   键入它应检查这两个顶点是否有不同的颜色。如果   他们没有,那么树的路径从祖先到后代,   与错误的边缘一起形成一个奇数周期,即   从算法返回以及图形的结果   不是二分的。但是,如果算法终止而未检测到   这种奇怪的循环,然后每个边缘必须正确着色,   并且算法返回着色以及结果   图是二分的。

答案 1 :(得分:0)

我甚至使用了递归解决方案,但这个也传递了相同数量的情况。我是否会留下任何特殊情况处理?

以下是问题的递归解决方案:

static void dfs(int v, int curr) {
        state[v] = true;
        color[v] = curr;

        for (int i = 0; i < numofemployees; i++) {
            if (adjmatrix[v][i] == 1) {
                if (color[i] == curr) {
                    bipartite = false;
                    return;
                }

                if (!state[i])
                    dfs(i, curr == 1 ? 2 : 1);
            }
        }
    }

我从main()调用此函数作为dfs(0,1),其中0是起始顶点,1是其中一种颜色