Tree
Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2104 Accepted Submission(s): 607
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.
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个数,问将他们都连通的最小费用。
最小生成树 【prime】【kruskal】,判断素数是要打表。
已AC代码一:【kruskal】
#include<cstdio>
#include<cstring>
#include<algorithm>
#define M 400000
using namespace std;
struct NODE{
int u,v,w;
}s[M];
int per[650],N[650],p[M],n;
void y_dabiao()//素数为 0
{
int i,j;
memset(p,0,sizeof(p));
for(i=2;i<M;++i)
{
if(p[i]==0)
{
for(j=i+i;j<M;j+=i)
{
p[j]=1;
}
}
}
p[1]=1;
}
bool cmp(NODE a,NODE b)
{
return a.w<b.w;
}
void into()
{
for(int i=0;i<=n;++i)
per[i]=i;
}
int find(int x)
{
return x == per[x] ? x:per[x]=find(per[x]);
}
int join(int a,int b)
{
int fa=find(a);
int fb=find(b);
if(fa != fb)
{
per[fa]=fb;
return 1;
}
return 0;
}
int main()
{
y_dabiao();
int T,i,j,d,m,k;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(i=1;i<=n;++i)
scanf("%d",&N[i]);
into();
k=0;
for(i=1;i<=n;++i)
{
for(j=i+1;j<=n;++j)
{
d=N[i]-N[j];
if(d<0)
d=(-1)*d;
if(p[N[i]]==0 || p[N[j]]==0 || p[N[i]+N[j]]==0)
{
m=min(d,min(N[i],N[j]));
s[k].u=i;
s[k].v=j;
s[k].w=m;
k++;
}
}
}
sort(s,s+k,cmp);
int sum=0;
for(i=0;i<k;++i)
{
if(join(s[i].u,s[i].v))
{
sum+=s[i].w;
}
}
int flag=0;
for(i=1;i<=n;++i)
{
if(per[i] == i)
{
flag++;
}
if(flag>1)
break;
}
if(flag>1)
printf("-1\n");
else
printf("%d\n",sum);
}
return 0;
}
已AC代码二:
【prime】
#include<cstdio>
#include<cstring>
#define M 1000010
#define INF 0x3f3f3f
int N[650],p[M],n;
int map[650][650],vis[650],cost[650];
void y_dabiao()//素数为 0
{
int i,j;
memset(p,0,sizeof(p));
for(i=2;i<M;++i)
{
if(p[i]==0)
{
for(j=i+i;j<M;j+=i)
{
p[j]=1;
}
}
}
p[1]=1;
}
int min(int x,int y)
{
return x<y?x:y;
}
void prime()
{
int i,j,pos,min,sum=0;
for(i=1;i<=n;++i)
{
vis[i]=0;
cost[i]=map[1][i];
}
vis[1]=1;
for(i=1;i<n;++i)
{
min=INF;
for(j=1;j<=n;++j)
{
if(vis[j]==0 && min>cost[j])
{
pos=j;
min=cost[j];
}
}
if(min>=INF)
{
printf("-1\n");
return ;
}
vis[pos]=1;
sum+=min;
for(j=1;j<=n;++j)
if(vis[j]==0 && cost[j]>map[pos][j])
cost[j]=map[pos][j];
}
printf("%d\n",sum);
return ;
}
int main()
{
y_dabiao();
int T,i,j,d;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(i=1;i<=n;++i)
scanf("%d",&N[i]);
memset(map,INF,sizeof(map));
for(i=1;i<=n;++i)
{
for(j=i+1;j<=n;++j)
{
d=N[i]-N[j];
if(d<0)
d=(-1)*d;
if(p[N[i]]==0 || p[N[j]]==0 || p[N[i]+N[j]]==0)
map[i][j]=map[j][i]=min(map[i][j],min(d,min(N[i],N[j])));
}
}
prime();
}
return 0;
}