并查集之情侣牵手

题目: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 }

 

posted @ 2022-05-02 17:09  coyote25  阅读(29)  评论(0编辑  收藏  举报