/*
hdu 2682 Tree 最小生成树
真的没有看出来是最小生成树
kruskal
*/
#include<stdio.h>
#include<stdlib.h>
int prime[2001000];
int map[601][601],set[601];
#include<math.h>
inline int min(int a,int b){return a<b?a:b;}
struct e
{
int x,y,w;
}b[500000];
int n,num,nei[601];
int cmp(const void *a,const void *b)//按边的权排序
{
struct e *c=(struct e *)a,*d=(struct e *)b;
return c->w-d->w;
}
int root(int i)
{
while(set[i]!=i)
i=set[i];
return i;
}
int kruskal()
{
int i,ding=0,xx,yy,r=0;
for(i=1;i<=n;i++)
set[i]=i;
for(i=2;i<=n;i++)
{
xx=root(b[ding].x);
yy=root(b[ding].y);
while(xx==yy)//寻找不会产生回路的边
{
ding++;
if(ding>num)
break;
xx=root(b[ding].x);
yy=root(b[ding].y);
}
if(ding>num)
break;
if(xx<yy)
set[yy]=xx;
else set[xx]=yy;
r+=b[ding].w;
ding++;
}
ding=0;
for(i=1;i<=n;++i)
if(set[i]==i)
ding++;
if(ding>1||ding>num)
return -1;
return r;
}
void su()
{
//0 su
prime[0]=prime[1]=1;
for(int i=2;i<1500;++i)
{
if(!prime[i])
{
for(int j=i+i;j<2001000;j+=i)
{
prime[j]=1;
}
}
}
}
int main()
{
int i,j,t;
su();
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&nei[i]);
num=0;
for(i=1;i<=n;++i)
{
for(j=1;j<=n;++j)
{
if(i==j) continue;
if(prime[nei[i]]==0||prime[nei[j]]==0||prime[nei[i]+nei[j]]==0)
{
b[num].x=i;
b[num].y=j;
b[num++].w=min(min(nei[i],nei[j]),abs(nei[i]-nei[j]));
}
}
}
qsort(b,num,sizeof(b[0]),cmp);
printf("%d\n",kruskal());
}
return 0;
}
hdu 2682 Tree 最小生成树
最新推荐文章于 2019-08-20 20:51:00 发布