leetcode886. 可能的二分法(hard)(dfs用於染色問題)

給定一組 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;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章