20221016 - 886. Possible Bipartition 可能的二分法(搜索)

88 阅读1分钟

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.

Example 1

Input: n = 4, dislikes = [[1,2],[1,3],[2,4]]
Output: true
Explanation: group1 [1,4] and group2 [2,3].

Example 2

Input: n = 3, dislikes = [[1,2],[1,3],[2,3]]
Output: false

Example 3

Input: n = 5, dislikes = [[1,2],[2,3],[3,4],[4,5],[1,5]]
Output: false

Constraints

  • 1 <= n <= 2000
  • 0 <= dislikes.length <= 1e4
  • dislikes[i].length == 2
  • 1 <= dislikes[i][j] <= n
  • ai < bi
  • All the pairs of dislikes are unique.

Solution

很暴力的 BFS ,注意可能有若干个非连通图。

bp[i] 表示分组,0 表示第一组,1 表示第二组

bool possibleBipartition(int n, int** dislikes, int dislikesSize, int* dislikesColSize){
    if (n == 1) return true;
    int i, j, i1, i2, bp[n + 1], G[n + 1][n + 1];
    int front, rear, queue[n];
    for (i = 0; i < n + 1; i++) {
        bp[i] = -1;
    }
    for (i = 0; i < n + 1; i++) {
        for (j = 0; j < n + 1; j++) {
            G[i][j] = G[j][i] = 0;
        }
    }
    for (i = 0; i < dislikesSize; i++) {
        i1 = dislikes[i][0];
        i2 = dislikes[i][1];
        G[i1][i2] = G[i2][i1] = 1;
    }
    front = rear = 0;
    queue[rear++] = 1;
    bp[1] = 0;
    while (front != rear) {
        i = queue[front++];
        for (j = 1; j < n + 1; j++) {
            if (G[i][j] == 1) {
                if (bp[j] == -1) {
                    bp[j] = !bp[i];
                    queue[rear++] = j;
                }
                else if (bp[i] == bp[j])
                    return false;
            }
        }
        // 确定整个图是否遍历完全
        if (front == rear) {
            for (i = 1; i < n + 1; i++) {
                if (bp[i] == -1) {
                    bp[i] = 0; //不能少了这一步染色,因为是非连通图,染哪种不影响
                    queue[rear++] = i;
                    break;
                }
            }
        }
    }
    return true;
}

题目链接:886. 可能的二分法 - 力扣(LeetCode)