leetcode 886. 可能的二分法(DFS,染色,種類並查集)
阿新 • • 發佈:2020-11-21
題目連結
題意:
給定一組N人(編號為1, 2, ..., N),我們想把每個人分進任意大小的兩組。
每個人都可能不喜歡其他人,那麼他們不應該屬於同一組。
形式上,如果 dislikes[i] = [a, b],表示不允許將編號為 a 和 b 的人歸入同一組。
當可以用這種方法將所有人分進兩組時,返回 true;否則返回 false。
思路:
-
法一:DFS+染色
首先初始化所有節點的顏色為0,然後給沒有染色的節點染上1,給這個節點的相鄰節點染色上-1,以此類推,判斷相鄰的兩個節點顏色相同即可 -
法二:種類並查集
如果a和b不能是相同顏色,那麼我們可以合併(a,b+N),(b,a+N)為相同顏色,這樣每次判斷fa[a]和fa[b]相同即可
class Solution { public: //方法二:種類並查集 vector<int> fa; int findroot(int x){ if(fa[x]==x) return x; return fa[x]=findroot(fa[x]); } void merge(int a,int b){ a=findroot(a); b=findroot(b); fa[a]=b; } bool possibleBipartition(int N, vector<vector<int>>& dislikes){ fa=vector<int>(N*2+1,0);//開兩倍空間(a,b+N),(b,a+N)來存 //初始化fa[]陣列 for(int i=1;i<=2*N;i++) fa[i]=i; for(vector<int> tmp:dislikes){ int x=findroot(tmp[0]); int y=findroot(tmp[1]); if(x==y) return false; //合併(a,b+N) merge(tmp[0],tmp[1]+N); merge(tmp[1],tmp[0]+N); } return true; } //方法一: //DFS + 染色 // vector<int> col;//染色 // vector<unordered_set<int>> ed; // bool dfs(int c,int k){ // col[k]=c; // for(auto it=ed[k].begin();it!=ed[k].end();it++){ // if(col[*it]==col[k]) return false; // if(!col[*it] && !dfs(-1*c,*it)) return false; // } // return true; // } // bool possibleBipartition(int N, vector<vector<int>>& dislikes){ // col=vector<int>(N+1,0);//N個節點的顏色 // ed=vector<unordered_set<int>>(N+1); // for(vector<int> tmp:dislikes){ // ed[tmp[0]].insert(tmp[1]); // ed[tmp[1]].insert(tmp[0]);//創立鄰接連結串列 // } // for(int i=1;i<=N;i++){ // if(!col[i] && !dfs(1,i)) return false; // } // return true; // } // static bool cmp(vector<int> a,vector<int> b){ // if(a[0]==b[0]) return a[1]<b[1]; // return a[0]<b[0]; // } // bool possibleBipartition(int N, vector<vector<int>>& dislikes) { // vector<vector<int>> ans; // for(vector<int> tmp:dislikes){ // if(tmp[0]>tmp[1]) swap(tmp[1],tmp[0]); // ans.push_back(tmp); // } // sort(ans.begin(),ans.end()); // set<int> s1,s2; // for(vector<int> tmp:ans){ // if(s1.count(tmp[1]) || s2.count(tmp[0])) return false; // s1.insert(tmp[0]); // s2.insert(tmp[1]); // } // return true; // } };