LeeCode 1627 并查集 + 埃氏筛法

题意

传送门 LeeCode 1627. 带阈值的图连通性

题解

图的连通性使用并查集维护,对于节点直接连通性的判断,枚举点对求 g c d gcd gcd 复杂度 O ( n 2 l o g n ) O(n^2logn) O(n2logn)。考虑筛法,枚举大于 t h r e s h o l d threshold threshold 的因数,最坏复杂度 O ( n l o g n ) O(nlogn) O(nlogn);考虑伪质数,那么可被伪质数整除的因数筛的数字连通性都已经处理,那么可以使用埃氏筛法,最坏复杂度 O ( n l o g l o g n ) O(nloglogn) O(nloglogn)

class Solution
{
#define maxn 10005
public:
    int par[maxn], rnk[maxn];

    void init(int n)
    {
        for (int i = 1; i <= n; ++i)
        {
            par[i] = i, rnk[i] = 0;
        }
    }

    int find(int x)
    {
        return par[x] == x ? x : (par[x] = find(par[x]));
    }

    bool same(int x, int y)
    {
        return find(x) == find(y);
    }

    void unite(int x, int y)
    {
        x = find(x), y = find(y);
        if (x == y)
            return;
        if (rnk[x] > rnk[y])
            par[y] = x;
        else
        {
            par[x] = y;
            if (rnk[x] == rnk[y])
                ++rnk[y];
        }
    }
    
    vector<bool> areConnected(int n, int threshold, vector<vector<int>> &queries)
    {
        init(n);
        for (int i = threshold + 1; i <= (n >> 1); ++i)
        {
            if (par[i] != i)
                continue;
            for (int j = i << 1; j <= n; j += i)
            {
                unite(i, j);
            }
        }
        int m = queries.size();
        vector<bool> res(m);
        for (int i = 0; i < m; ++i)
        {
            auto &q = queries[i];
            res[i] = same(q[0], q[1]);
        }
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值