题面:已知2到n个节点,每个点的边长为两点的最小公倍数,求最小生成树。
解析:复杂度告诉我们最小生成树板子是行不通的。
我们知道互质的两个数的最小公倍数是两数的乘积,一个数是另一个数的因子则最小公倍数就是大的那个数。
所以只要我们将所有大于2的质数与2相连,其他合数与其某个因子相连,所得就是最小生成树。
代码
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll t; bool h[10000001]={0}; ll prime[10000001],num=1; void xs(int n){ for(int i=2;i<=n;i++){ if(h[i]==0) prime[num++]=i; for(int j=1;j<num&&i*prime[j]<=n;j++){ h[i*prime[j]]=true; if(i%prime[j]==0)break; } } } int main(){ ll n; xs(10000000); scanf("%lld",&t); while(t--){ ll ans=0; scanf("%lld",&n); for(ll i=3;i<=n;i++) { if(h[i]==0) ans+=2*i; else ans+=i; } printf("%lld\n",ans); } }