hdu2682

/*
分析:
    最小生成树水题,就当又温习了一遍了,囧~


                   2012-09-16
*/








#include"stdio.h"
#include"math.h"
#include"string.h"
#include"stdlib.h"
int vi[611];
int prime[2000111];
struct A
{
	int a,b;
	int len;
}eage[180000];
int tot;


//并查集
int set[611];
void build(int n)
{
	int i;
	for(i=0;i<n;i++)	set[i]=i;
}
int find(int k)
{
	if(set[k]==k)	return k;
	set[k]=find(set[k]);
	return set[k];
}
void Union(int f1,int f2)
{
	set[f1]=f2;
}


int MIN(int a,int b)
{
	return a>b?b:a;
}
int cmp(const void *a,const void *b)
{
	struct A *c,*d;
	c=(struct A *)a;
	d=(struct A *)b;
	return c->len-d->len;
}
int main()
{
	int T;
	int n;
	int i,l;
	int temp;
	int f1,f2;
	int cost;


	memset(prime,-1,sizeof(prime));
	prime[0]=prime[1]=0;
	for(i=2;i<=2000000;i++)
	{
		if(prime[i]==-1)
		{
			for(temp=2*i;temp<=2000000;temp+=i)	prime[temp]=0;
		}
	}


	scanf("%d",&T);
	while(T--)
	{
		//读入
		scanf("%d",&n);
		for(i=0;i<n;i++)	scanf("%d",&vi[i]);
		//建边
		tot=0;
		for(i=0;i<n;i++)
		for(l=i+1;l<n;l++)
		{
			if(prime[vi[i]] || prime[vi[l]] || prime[vi[i]+vi[l]])
			{
				eage[tot].a=i;
				eage[tot].b=l;
				eage[tot].len=MIN(vi[i],MIN(vi[l],abs(vi[i]-vi[l])));
				tot++;
			}
		}
		qsort(eage,tot,sizeof(eage[0]),cmp);
		//最小树
		cost=0;
		build(n);
		for(i=0;i<tot;i++)
		{
			f1=find(eage[i].a);
			f2=find(eage[i].b);
			if(f1==f2)	continue;
			cost+=eage[i].len;
			Union(f1,f2);
		}
		//结果
		temp=0;
		for(i=0;i<n;i++)	if(set[i]==i)	temp++;
		if(temp>1)	printf("-1\n");
		else		printf("%d\n",cost);
	}
	return 0;
}


你可能感兴趣的:(hdu2682)