1. 程式人生 > >演算法分析week3 | 785. Is Graph Bipartite?

演算法分析week3 | 785. Is Graph Bipartite?

目錄

  1. 題目描述
  2. 解題過程
  3. 完整程式碼

題目描述

3.7

解題過程

這道題與書上習題3.7類似。二部圖是這樣的圖G=(V,E),其頂點集合可以被劃分為兩個子集(V = V1 ∪ V2 且 V1 ∩ V2 = Ф),並且子集內部的頂點之間沒有邊相連。

要判斷一個無向圖是否是二部圖,我們可以考慮這個圖是否可以用兩種顏色為它著色,有邊相連的兩個頂點需要著不同顏色。

首先,用一個數組subsets來記錄每個頂點的顏色,-1表示未著色,而0,1分別表示兩種不同的顏色。

        vector<int> subsets;
        for(int i = 0; i < graph.size(); i++) subsets.push_back(-1);

由於給定的圖可能由多個強連通部件構成,因此需要對每個頂點進行檢查。如果當前頂點已經著色,則可以跳過,因為這表示該頂點所在的強連通部件已經被著色了。如果有一個強連通部件不能用兩種顏色著色,則返回false,如果所有強連通部件都可以用兩種顏色著色,則返回true。

        for(int i = 0; i < graph.size(); i++) {
            if(subsets[i] != -1) continue;
            if(!explore(subsets, graph, i)) return false;
        }

explore使用深度優先遍歷

,對一個強連通部件進行著色。如果該部件不能用兩種顏色著色,則返回false。

    bool explore(vector<int>& subsets, vector<vector<int>>& graph, int i) {
        if(subsets[i] == -1) subsets[i] = 0;
        for(int j = 0; j < graph[i].size(); j++) {
            if(subsets[graph[i][j]] != -1) {
                if(subsets[graph[i][j]] == subsets[i]) return false;
                continue;
            }
            subsets[graph[i][j]] = !subsets[i];
            if(graph[graph[i][j]].size() > 0) {
                if(!explore(subsets, graph, graph[i][j])) return false;
            }
        }
        return true;
    }

這是個線性時間演算法,複雜度為O(V+E)

完整程式碼

class Solution {
public:
    bool isBipartite(vector<vector<int>>& graph) {
        vector<int> subsets;
        for(int i = 0; i < graph.size(); i++) subsets.push_back(-1);
        for(int i = 0; i < graph.size(); i++) {
            if(subsets[i] != -1) continue;
            if(!explore(subsets, graph, i)) return false;
        }
        return true;
    }
    bool explore(vector<int>& subsets, vector<vector<int>>& graph, int i) {
        if(subsets[i] == -1) subsets[i] = 0;
        for(int j = 0; j < graph[i].size(); j++) {
            if(subsets[graph[i][j]] != -1) {
                if(subsets[graph[i][j]] == subsets[i]) return false;
                continue;
            }
            subsets[graph[i][j]] = !subsets[i];
            if(graph[graph[i][j]].size() > 0) {
                if(!explore(subsets, graph, graph[i][j])) return false;
            }
        }
        return true;
    }
};