1. 程式人生 > >LeetCode:785. Is Graph Bipartite?(Week 6)

LeetCode:785. Is Graph Bipartite?(Week 6)

785. Is Graph Bipartite?

  • 題目
    Given an undirected graph, return true if and only if it is bipartite.

    Recall that a graph is bipartite if we can split it’s set of nodes into two independent subsets A and B such that every edge in the graph has one node in A and another node in B.

    The graph is given in the following form: graph[i]

    is a list of indexes j for which the edge between nodes i and j exists. Each node is an integer between 0 and graph.length - 1. There are no self edges or parallel edges: graph[i] does not contain i, and it doesn’t contain any element twice.

    Example 1:
    Input: [[1,3], [0,2], [1,3], [0,2]]
    Output: true
    Explanation: 
    The graph looks like this:
    0----1
    |    |
    |    |
    3----2
    We can divide the vertices into two groups: {0, 2} and {1, 3}.
    
    Example 2:
    Input: [[1,2,3], [0,2], [0,1,3], [0,2]]
    Output: false
    Explanation: 
    The graph looks like this:
    0----1
    | \  |
    |  \ |
    3----2
    We cannot find a way to divide the set of nodes into two independent subsets.
    

    Note:

    • graph will have length in range [1, 100].
    • graph[i] will contain integers in range [0, graph.length - 1].
    • graph[i] will not contain i or duplicate values.
    • The graph is undirected: if any element j is in graph[i], then i will be in graph[j].
  • 解題思路

    • 本題給了無向圖的邊,判斷這個圖是否是一個二分圖
    • 什麼是二分圖?

      二分圖又稱作二部圖,是圖論中的一種特殊模型。 設G=(V,E)是一個無向圖,如果頂點V可分割為兩個互不相交的子集(A,B),並且圖中的每條邊(i,j)所關聯的兩個頂點i和j分別屬於這兩個不同的頂點集(i in A,j in B),則稱圖G為一個二分圖。孤立點可以任意劃分在A或B集合。

    • 解法:
      • 使用BFS + 染色法
      • BFS以未被染色且非孤立點的點作為BFS搜尋的起點
      • 使用染色法,只使用兩種顏色,將與該點相鄰(存在一條邊)且未被染色的點染成與其不同的顏色,假如相鄰的點已被染色且顏色與該點相同,則證明該圖不是二分圖。
  • 實現程式碼

    // 染色法 + BFS
    
    class Solution {
    public:
        bool isBipartite(vector<vector<int>>& graph) {
        	int num = graph.size();
        	
        	bool colors[num] = {false};
        	int visited[num] = {0};
    
        	queue<int> q;
        	
        	for(int i = 0; i < num; ++i) {
        		if(graph[i].size() > 0 && visited[i] == 0) {
        			q.push(i);
        			visited[i] = 1;
    		    	
    		    	// bfs
    		    	while(!q.empty()) {
    		    		int top = q.front();
    		    		q.pop();
    		    		for(auto i : graph[top]) {
    		    			if(!visited[i]) {
    		    				visited[i] = 1;
    		    				colors[i] = !colors[top];
    		    				q.push(i);
    		    			}
    		    			if(colors[i] == colors[top])
    		    				return false;
    		    		}
    		    	}
        		}
        	}
    
        	return true;
        }
    };