Tree
Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1954 Accepted Submission(s): 573
Problem Description
There are N (2<=N<=600) cities,each has a value of happiness,we consider two cities A and B whose value of happiness are VA and VB,if VA is a prime number,or VB is a prime number or (VA+VB) is a prime
number,then they can be connected.What's more,the cost to connecte two cities is Min(Min(VA , VB),|VA-VB|).
Now we want to connecte all the cities together,and make the cost minimal.
number,then they can be connected.What's more,the cost to connecte two cities is Min(Min(VA , VB),|VA-VB|).
Now we want to connecte all the cities together,and make the cost minimal.
Input
The first will contain a integer t,followed by t cases.
Each case begin with a integer N,then N integer Vi(0<=Vi<=1000000).
Each case begin with a integer N,then N integer Vi(0<=Vi<=1000000).
Output
If the all cities can be connected together,output the minimal cost,otherwise output "-1";
Sample Input
2
5
1
2
3
4
5 4
4
4
4
4
Sample Output
4
-1
题意:两个数A和B。 A或B或者A+B是素数就表示A与B能连通。A与B连通的费用是A,B,A-B的绝对值这三个数中最小的值。
先给出n个数,问将他们都连通的最小费用。
最小生成树,推断素数是要打表。
prim算法,代码例如以下:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#define INF 0x3f3f3f
int map[610][610],sum,prime[1000010],n; void is_primes()//素数打表
{
int i,j;
prime[0]=prime[1]=1;
for(i=2;i*i<=1000000;++i)
{
if(prime[i])
continue;
for(j=i*i;j<=1000000;j=i+j)
prime[j]=1;
}
} int min(int a,int b)
{
return a<b?a:b;
} void prim()
{
sum=0;
int i,j,next,min;
int lowcost[610],visit[610];
memset(visit,0,sizeof(visit));
for(i=0;i<n;++i)
lowcost[i]=map[0][i];
visit[0]=1;//注意从零開始的
for(i=1;i<n;++i)
{
min=INF;
for(j=0;j<n;++j)
{
if(!visit[j]&&min>lowcost[j])
{
min=lowcost[j];
next=j;
}
}
if(min==INF)
{
printf("-1\n");
return ;
}
sum+=min;
visit[next]=1;
for(j=0;j<n;++j)
{
if(!visit[j]&&lowcost[j]>map[next][j])
lowcost[j]=map[next][j];
}
}
printf("%d\n",sum);
} int main()
{
is_primes();
int t,a[610],i,j;
scanf("%d",&t);
while(t--)
{
memset(map,INF,sizeof(map));
scanf("%d",&n);
for(i=0;i<n;++i)
scanf("%d",&a[i]);
for(i=0;i<n;++i)
{
for(j=0;j<n;++j)
{
if(!prime[a[i]]||!prime[a[j]]||!prime[a[i]+a[j]])//满足素数条件记录入数组
map[i][j]=map[j][i]=min(min(a[i],a[j]),abs(a[i]-a[j]));
}
}
prim();
}
return 0;
}