题解 | 隐匿社交网络

隐匿社交网络

https://www.nowcoder.com/practice/2870f9db6aeb4eb08fbd6460397f9bf4

#include <bits/stdc++.h>
using namespace std;
#define ll unsigned long long
#define fo(i,a,b) for(int i=a;i<b;i++) // 定义一个循环宏,用于简化循环代码

vector<ll>a(64); // 并查集的父数组,用于记录每个位的父节点

// 并查集的查找函数,带路径压缩
int find(int x){
    if(a[x]!=x){ // 如果当前节点不是根节点
        a[x]=find(a[x]); // 递归查找根节点,并进行路径压缩
    }
    return a[x]; // 返回根节点
}

// 并查集的合并函数
void arrage_sum(int x,int y){
    x=find(x); // 找到x的根节点
    y=find(y); // 找到y的根节点
    if(x!=y){ // 如果x和y不在同一个集合
        a[x]=a[y]; // 将x的根节点指向y的根节点,合并两个集合
    }
}

int main() {
    ll n; // 测试用例的数量
    cin>>n;
    while(n--){ // 对每个测试用例进行处理
        ll m; // 当前测试用例的权重数量
        cin>>m;
        vector<vector<int>>vv(64); // 用于记录每个位上为1的权重的下标
        vector<ll>v(m); // 存储当前测试用例的所有权重
        fo(i,0,64)a[i]=i; // 初始化并查集,每个位是一个独立的集合
        fo(i,0,m){ // 遍历每个权重
            cin>>v[i]; // 读取权重
            vector<ll>b; // 用于记录当前权重的二进制表示中为1的位
            for(int j=0;j<64;j++){ // 遍历每个位
                if((v[i]>>j)&1){ // 如果当前位是1
                    vv[j].emplace_back(i); // 记录该权重的下标
                    b.emplace_back(j); // 记录该位
                }
            }
            if(b.size()>1){ // 如果当前权重有多个1位
                fo(k,1,b.size()){ // 遍历这些1位
                    arrage_sum(b[k-1],b[k]); // 将这些位对应的集合合并
                }
            }
        }
        fo(i,0,64){ // 遍历每个位
            int x=find(i); // 找到该位的根节点
            if(x!=i){ // 如果该位不是根节点
                fo(j,0,vv[i].size()){ // 将该位的所有权重下标合并到根节点对应的集合
                    vv[x].emplace_back(vv[i][j]);
                }
                sort(vv[x].begin(),vv[x].end()); // 对合并后的集合进行排序
            }
        }
        int ans=0; // 用于记录最大的社交网络大小
        fo(i,0,64){ // 遍历每个集合
            ll flag=0; // 用于记录重复的权重下标
            if(vv[i].size()>1){ // 如果集合大小大于1
                fo(j,1,vv[i].size()){ // 遍历集合
                    if(vv[i][j]==vv[i][j-1]){ // 如果有重复的权重下标
                        flag++; // 增加重复计数
                    }
                }
            }
            ans=max(ans,int(vv[i].size()-flag)); // 更新最大的社交网络大小
        }
        cout<<ans<<'\n'; // 输出结果
    }
    return 0;
}

全部评论

相关推荐

purcoter:虚拟货币预测正确率百分之99,还要找工作干嘛,不早就财富自由了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务