并查集之情侣牵手
题目:https://leetcode-cn.com/problems/couples-holding-hands/
LeetCode 765
02 34 15 67
这样的初始座位我们可以看做:首先一队是情侣是属于一个老大的,同坐一个椅子的,我们也认为他是属于一个老大;(即同属一个连通域)
最后输出的结果为n-老大的个数;
1 #include <bits/stdc++.h> 2 using namespace std; 3 //并查集的应用 4 class UnionFind{ 5 private: 6 //记录并查集集合个数 7 int count ; 8 //存放老大 9 vector<int> parent; 10 public: 11 //返回并查集集合个数 12 int getCount(){ 13 return count; 14 } 15 16 //构造函数 17 UnionFind(int n ){ 18 this->count = n; 19 this->parent = vector<int> (n,0); 20 for(int i =0;i<n;i++){ 21 //自己的老大是自己 22 parent[i] = i; 23 } 24 } 25 26 //查询老大 27 int find(int x ){ 28 //查到最大的老大为止,这里用了路径压缩法; 29 while(x!=parent[x]){ 30 parent[x] = parent[parent[x]]; 31 x = parent[x]; 32 } 33 return x; 34 } 35 36 //让两个人认同一个老大 37 void setUnion(int x,int y){ 38 int parentx = find(x); 39 int parenty = find(y); 40 if(parentx == parenty) return; 41 else{ 42 //让其中一个人的老大认另外一个人为老大 43 parent[parentx] = parenty; 44 count--; 45 } 46 } 47 }; 48 int main() { 49 int n = 0; 50 //n对情侣 51 cin >>n; 52 int m =2*n; 53 //row是目前情侣的位置 54 vector<int> row; 55 while(m-->0){ 56 int num ; 57 cin >>num; 58 row.emplace_back(num); 59 } 60 //明确:情侣的编号是满足,index1/2 == index2/2;则index1与index2是情侣; 61 //建立并查集,初始集合为n; 62 UnionFind * couple = new UnionFind(n); 63 for(int i = 0;i<row.size();i=i+2){ 64 couple->setUnion(row[i]/2,row[i+1]/2); 65 } 66 cout<< n-couple->getCount()<<endl; 67 }