給定一組 N 人(編號爲 1, 2, ..., N), 我們想把每個人分進任意大小的兩組。
每個人都可能不喜歡其他人,那麼他們不應該屬於同一組。
形式上,如果 dislikes[i] = [a, b],表示不允許將編號爲 a 和 b 的人歸入同一組。
當可以用這種方法將每個人分進兩組時,返回 true;否則返回 false。
示例 1:
輸入:N = 4, dislikes = [[1,2],[1,3],[2,4]]
輸出:true
解釋:group1 [1,4], group2 [2,3]
示例 2:
輸入:N = 3, dislikes = [[1,2],[1,3],[2,3]]
輸出:false
示例 3:
輸入:N = 5, dislikes = [[1,2],[2,3],[3,4],[4,5],[1,5]]
輸出:false
思路:
題目可以抽象成用兩種顏色,給圖染色,這裏的圖是有好幾個散着的圖組成的
用dfs去給圖染色
class Solution {
public:
bool possibleBipartition(int N, vector<vector<int>>& dislikes) {
if(dislikes.empty()) return true;
graph = vector<vector<int>>(N);
for(auto d:dislikes){
graph[d[0]-1].push_back(d[1]-1);
graph[d[1]-1].push_back(d[0]-1);
}
colors = vector<int>(N,0);
for(int i = 0;i < N;i++){
// 0:沒有被訪問過,-1和1是兩種着色
// 如果沒有被訪問過,且dfs判斷結果爲false,則不能染色
// 這裏初始設置1或者-1,其實都行,因爲dfs會把一整個連通圖給走完,所以這裏入口其實只初始化了起點的顏色
if(colors[i] == 0 && !dfs(i,1)) return false;
}
return true;
}
private:
vector<vector<int>> graph;
vector<int> colors;
bool dfs(int cur,int cur_color){
colors[cur] = cur_color;
for(auto next:graph[cur]){
if(colors[next] == cur_color) return false;
// 沒有被訪問過,則置-cur_color,通過dfs其實可以把相關的一條圈都走完
if(colors[next] == 0 && !dfs(next,-cur_color)) return false;
}
return true;
}
};