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.
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).
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
先用欧拉筛求出所有的素数,然后读入每一个点,将它与之前的所有点分别判断,符合条件,就建边,最后用prim算法求最小生成树,还要遍历一边所有点,如果有的点未被标记,就说明这个点没有连通
查了好多遍,测试数据也过了,也不超时,一直WA。哪位大神帮我看看 orz
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#define inf 0x3f3f3f3f
using namespace std;
struct edge
{
int to,w,next;
}e[1000005];
int node[100005],check[2000005],pri[200001],cntt;
int head[1000005],dis[100005],cnt,n,tot,ans,now;
bool vis[100005];
void euler(int n)
{
for(int i=2;i<=n;i++)
{
if(!check[i])
pri[++cntt]=i;
for(int j=1;pri[j]*i<=n;j++)
{
check[pri[j]*i]=1;
if(i%pri[j]==0)
break;
}
}
}
void add(int u,int v,int w)
{
e[++cnt].to=v;
e[cnt].w=w;
e[cnt].next=head[u];
head[u]=cnt;
}
void prim()
{
for(int i=2;i<=n;i++)
dis[i]=inf;
for(int i=head[1];i;i=e[i].next)
dis[e[i].to]=min(dis[e[i].to],e[i].w);
now=1;
vis[now]=1;
while(++tot<n)
{
int minn=inf;
for(int i=1;i<=n;i++)
{
if(!vis[i]&&minn>dis[i])
{
minn=dis[i];
now=i;
}
}
if(minn==inf)
break;
vis[now]=1;
ans+=minn;
for(int i=head[now];i;i=e[i].next)
{
int v=e[i].to;
if(dis[v]>e[i].w&&!vis[v])
dis[v]=e[i].w;
}
}
for(int i=1;i<=n;i++)
if(!vis[i])
ans=-1;
}
int main()
{
int t;
cin>>t;
euler(2000005);
while(t--)
{
cin>>n;
cnt=tot=ans=0;
memset(vis,0,sizeof(vis));
memset(head,0,sizeof(head));
for(int i=1;i<=n;i++)
{
scanf("%d",&node[i]);
for(int j=1;j<i;j++)
{
if(!check[node[i]]||!check[node[j]]||!check[node[i]+node[j]])
{
int r=node[i]-node[j];
if(r<0)
r*=-1;
int d=min(node[i],node[j]);
d=min(d,r);
add(i,j,d);
add(j,i,d);
}
}
}
prim();
cout<<ans<<endl;
}
return 0;
}