我们读题可以发现
这道题其实就是 给出n个点 m条边
要求把所有点联通后 所用的边的权值和最小
我们在往下看 可以发现下面gachi只是把权值为质数的边权值变成0
所有我们只需要读入边的时候把权值为质数的边 权值替换成0
然后跑一遍最小生成树
只不过需要的质数范围大 需要线性素数筛
这题其实是个签到题.............
#include<bits/stdc++.h>
using namespace std;
struct bian {
long long int a, b, v;
}a[210000];
long long int n, m, bcj[210000], mn;
long long int ss[1100000] = { 0,2 }, sz;
long long int find(long long int fd) {
return bcj[fd] == fd ? fd : bcj[fd] = find(bcj[fd]);
}
bool cmp(struct bian q, struct bian p) {
return q.v < p.v;
}
bool hs[11000000] = { 1,1 };
long long int k,num,sum,fk;
int main() {
//freopen("11.in", " r ", stdin);
//freopen("11.out", " w ", stdout);
cin >> n >> m>>k;
for (long long int i = 0; i <= n; i++)
{
bcj[i] = i;
}
for (long long int i = 0; i < m; i++)
{
long long int ab, bb, vq;
cin >> ab >> bb >> vq;
a[i].a = ab;
a[i].b = bb;
a[i].v = vq;
fk=max(fk,vq);
}
for (long long int i = 2; i <= fk; i++)
{
if (hs[i] == false)
ss[++sz] = i;
for (long long int j = 1; j <= sz && i * ss[j] <= fk; j++)
{
if (i * ss[j] > fk)break;
hs[ss[j] * i] = 1;
if (i % ss[j] == 0)
{
break;
}
}
}
for (long long int i = 0; i < m; i++)
{
if (hs[a[i].v] == false)
{
a[i].v = 0;
}
}
sort(a, a + m, cmp);
for (long long int i = 0; i < m; i++)
{
long long int fa = find(a[i].a);
long long int fb = find(a[i].b);
if (fa != fb)
{
bcj[fb] = fa;
num++;
sum += a[i].v;
}
if (num == (n - 1)) {
break;
}
}
if (num == (n - 1)&&sum<k)
cout << "wmmxycwdjdwdlnljbzwtskirakira";
else
cout << "wmmxycwdjdwdlnljbzwtsfljt";
return 0;
}
京公网安备 11010502036488号