題目大意
將N個人劃分爲兩組,每個人可能不喜歡其他人,即不能和不喜歡的分到一組,問是否能夠成功劃分。
輸入
N
和dislike[][2]
分別表示人的個數和不喜歡的列表。例如N = 4, dislikes = [[1,2],[1,3],[2,4]]
,表示4個人,其中1與2,1與3,2與4不能分到同一組。
思路
類似並查集,因爲不喜歡是成對出現的,所以記錄每個元素所屬的集合
以及不喜歡的集合
。對於不喜歡列表中的每一對(x, y)
,如若
- x,y都未加入任何集合 - 以他們自己爲根元素初始化兩個新集合,且x的
不喜歡集合
爲y,y的不喜歡集合
爲x - y未加入任何集合,x屬於某個集合
rootx
- 將y加入到x的不喜歡集合
中,將y的不喜歡集合
設置爲x - x未加入任何集合,y屬於某個集合
rooty
- 同上,將x加入到y的不喜歡集合,將x的不喜歡集合設置爲y - x,y都加入了某個集合
rootx,rooty
- 若rootx==rooty
,則return false
,無法劃分
若最後一種情況未出現,則表示可以劃分爲兩個集合
代碼
struct T{
int root, oproot;
T(){ root = oproot = -1;}
bool empty() { return root == -1; }
void setRoot(int root, int oproot) { this->root = root, this->oproot = oproot; }
};
class Solution {
public:
bool possibleBipartition(int N, vector<vector<int>>& dislikes) {
vector<T> roots(N + 1);
for (auto tmpvec: dislikes) {
int x = tmpvec[0], y = tmpvec[1];
T &xt = roots[x], &yt = roots[y];
if (xt.empty() && yt.empty()) {
xt.setRoot(x, y);
yt.setRoot(y, x);
} else if (xt.empty()) {
xt.setRoot(yt.oproot, yt.root);
} else if (yt.empty()){
yt.setRoot(xt.oproot, xt.root);
} else {
if (xt.root == yt.root) return false;
}
}
return true;
}
};
總結
討論版中有以二分圖爲思路使用BFS進行紅藍着色的,感興趣的可以參考這裏。