(LeetCode 886)可能的二分法 [01著色問題,dfs模擬]
阿新 • • 發佈:2019-01-01
886. 可能的二分法
給定一組 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
提示:
1 <= N <= 2000
0 <= dislikes.length <= 10000
1 <= dislikes[i][j] <= N
dislikes[i][0] < dislikes[i][1]
對於 dislikes[i] == dislikes[j] 不存在 i != j
分析:
本題就是直接使用DFS(或BFS)進行模擬。將所有人分為兩組,就是給所有人在0,1兩種顏色上著色,使其不衝突。
首先所有的節點都沒有著色,標記為-1。
對任意的聯通分量,第一個節點我們可以隨意著色,(著色為1),然後進行DFS對其他相鄰的節點進行著色。
若該節點沒有被著色,則將其著色為另外一種顏色,並遞迴對其相鄰節點進行著色。
若該節點已經著色,則只需判斷這兩個相鄰的節點的顏色是否相同,相同則存在衝突。
AC程式碼:
class Solution { public: int c[2019]; vector<int> e[2019]; int dfs(int id,int color) { c[id] = color; int ans = 1; for(int i=0;i<e[id].size();i++) { if(c[e[id][i]] == -1) ans &= dfs(e[id][i],color^1); else if(c[e[id][i]] == color) { ans = 0; break; } } return ans; } bool possibleBipartition(int N, vector<vector<int>>& dislikes) { if(N<=2) return true; memset(c,-1,sizeof(c)); int m = dislikes.size(); for(int i=0;i<m;i++) { e[dislikes[i][0]].push_back(dislikes[i][1]); e[dislikes[i][1]].push_back(dislikes[i][0]); } int ans = 1; for(int i=1;i<=N;i++) { if(c[i] == -1) ans &= dfs(i,1); } return ans; } };