1364 字
5 分钟阅读
隐匿社交网络 / NC287758

原题链接:https://ac.nowcoder.com/acm/problem/287758

牛客网有一个名为牛爱网神秘的入口。这天,牛可乐正在策划牛爱网的全新社交活动。
每个人的账号在初始时都会被分配一个权重,第 i 个账号的权重为 w_i 。对于任意的两个账号 i j ,如果权重满足 ( w_i and w_j \ge 1 ) ,那么就会被分配到同一个社交网络。
现在,牛可乐已经为 n 个账号分配了权重,他想知道,包含账号数量最多的社交网络中,包含多少个账号。
牛爱网的日常维护工作忙坏了牛可乐,请你帮帮他。

其中, and 表示按位与运算。

思路: 将每一个二进制位第一次出现1的权重用map存起来,每有权重这个二进制位是1,就用并查集合并两个账号,最终枚举所有集合中账号数最多的即可。

我的AC代码:

#include <bits/stdc++.h>
#define all(a) (a).begin(),(a).end()
using namespace std;

using ll = long long;
using ull = unsigned long long;

const int N = 1e5 + 50;

vector<int> dsu (N,0);
vector<int> mysize (N,0);

void init(int n){
    for(int i = 1;i <= n;i++){
        dsu[i] = i;
        mysize[i] = 1;
    }
}

int find(int n){
    queue<int> q;
    while(dsu[n] != n){
        q.push(n);
        n = dsu[n];
    }
    while(!q.empty()){
        dsu[q.front()] = n;
        q.pop();
    }
    return n;
}

void uni(int a,int b){
    int fa = find(a);
    int fb = find(b);
    if(fa != fb){
        dsu[fa] = fb;
        mysize[fb] += mysize[fa];
        mysize[fa] = 0;
    }
}

void solve(){
    int n;
    cin >> n;
    dsu = vector<int> (N,0);
    mysize = vector<int> (N,0);
    init(n);
    unordered_map<int,int> mp;
    for(int i = 1;i <= n;i++){
        ll x;
        cin >> x;
        ll tmp = x;
        int cnt = 0;
        while(tmp > 0){
            if(tmp & 1){
                if(mp.find(cnt) != mp.end()){
                    uni(mp[cnt],i);
                }else{
                    mp[cnt] = i;
                }
            }
            cnt++;
            tmp >>= 1;
        }
    }
    cout << *max_element(all(mysize)) << "\n";
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    cin >> t;
    while(t--){
        solve();
    }
    return 0;
}

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注