题意:
给定一个由不同正整数的组成的非空数组 A,考虑下面的图:
有 A.length 个节点,按从 A[0] 到 A[A.length - 1] 标记;
只有当 A[i] 和 A[j] 共用一个大于 1 的公因数时,A[i] 和 A[j] 之间才有一条边。
返回图中最大连通组件的大小。
数据范围:
1 <= A.length <= 20000
1 <= A[i] <= 100000
解法:
对每个数质因子分解
用并查集将每个数和自己的所有>1的因子合并,统计连通块个数即可.
复杂度O(n*sq).
code:
const int maxm=1e5+5;
int pre[maxm],cnt[maxm];
int ffind(int x){
return pre[x]==x?x:pre[x]=ffind(pre[x]);
}
class Solution {
public:
void init(){
for(int i=0;i<maxm;i++)pre[i]=i,cnt[i]=0;
}
int largestComponentSize(vector<int>& a){
init();
for(auto x:a)cnt[x]++;
for(auto x:a){
int f=ffind(x);
for(int i=2;i*i<=x;i++){
if(x%i==0){
int ff=ffind(i);
if(f!=ff){
pre[ff]=f;
cnt[f]+=cnt[ff];
}
int fff=ffind(x/i);
if(f!=fff){
pre[fff]=f;
cnt[f]+=cnt[fff];
}
}
}
}
int ans=0;
for(int i=0;i<maxm;i++){
ans=max(ans,cnt[i]);
}
return ans;
}
};