無向圖的遍歷_判斷二分圖
阿新 • • 發佈:2020-12-25
技術標籤:無向圖的遍歷
難度:中等
給定一個無向圖graph,當這個圖為二分圖時返回true。
如果我們能將一個圖的節點集合分割成兩個獨立的子集A和B,並使圖中的每一條邊的兩個節點一個來自A集合,一個來自B集合,我們就將這個圖稱為二分圖。
graph將會以鄰接表方式給出,graph[i]表示圖中與節點i相連的所有節點。每個節點都是一個在0到graph.length-1之間的整數。這圖中沒有自環和平行邊: graph[i] 中不存在i,並且graph[i]中沒有重複的值。
示例 1:
輸入: [[1,3], [0,2], [1,3], [0,2]]
輸出: true
解釋:
無向圖如下:0----1
| |
| |
3----2
我們可以將節點分成兩組: {0, 2} 和 {1, 3}。
示例 2:
輸入: [[1,2,3], [0,2], [0,1,3], [0,2]]
輸出: false
解釋:
無向圖如下:
0----1
| |
| |
3----2
我們不能將節點分割成兩個獨立的子集。
注意:
graph 的長度範圍為 [1, 100]。
graph[i] 中的元素的範圍為 [0, graph.length - 1]。
graph[i] 不會包含 i 或者有重複的值。
圖是無向的: 如果j 在 graph[i]裡邊, 那麼 i 也會在 graph[j]裡邊。
來源:力扣(LeetCode)
連結:力扣
染色法,深度優先遍歷,廣度優先遍歷
深度優先遍歷還是很巧妙的,廣度優先遍歷回溯做的比較麻煩,也可能是我沒想到好的方法。
// 廣度優先遍歷BFS class Solution { public: bool isBipartite(vector<vector<int>>& graph) { int size = graph.size(); vector<int> color(size, 0); return bfs(graph, color, 0, size); } bool bfs(vector<vector<int>>& graph, vector<int> &color, int index, int &len){ if(len == index) return true; if(color[index] == 0){ color[index] = 1; if(bfs(graph, color, index, len)) return true; color[index] = -1; return bfs(graph, color, index, len); } else{ int c = color[index] * -1; vector<int> temp; for(int i : graph[index]){ if(color[i] == color[index]) return false; temp.push_back(color[i]); } for(int i : graph[index]) color[i] = c; if(bfs(graph, color, index + 1, len)) return true; for(int i = 0; i < temp.size(); i++) color[graph[index][i]] = temp[i]; return false; } } };
class Solution {
public:
bool isBipartite(vector<vector<int>>& graph) {
int size = graph.size();
vector<int> colors(size, 0);
for(int i = 0; i < size; i++){
if(colors[i] == 0 && !dfs(graph, colors, i, 1))
return false;
}
return true;
}
bool dfs(vector<vector<int>>& graph, vector<int>& colors, int index, int color){
colors[index] = color;
for(int i : graph[index]){
if(colors[i] == 0 && !dfs(graph, colors, i, -color))
return false;
if(colors[i] == color)
return false;
}
return true;
}
};