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;
}