Tree
Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1760 Accepted Submission(s): 514
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
最小生成树,附上两种代码。 提醒此题需要用打表法,要不会超时。
kruskal:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
#define max 360000+10
#define M 1000000+1
using namespace std;
int set[1000],prime[M];
struct line
{
int start;
int end;
int cost;
}num[max];
bool cmp(line a,line b)
{
return a.cost<b.cost;
}
int find(int p)
{
int child=p;
int t;
while(p!=set[p])
p=set[p];
while(child!=p)
{
t=set[child];
set[child]=p;
child=t;
}
return p;
}
void merge(int x,int y)
{
int fx=find(x);
int fy=find(y);
if(fx!=fy)
set[fx]=fy;
}
void dabiao()
{
int i,j;
memset(prime,0,sizeof(prime));//素数为0
for(i=2;i<M;i++)
{
if(!prime[i])
{
for(j=2*i;j<M;j+=i)
{
prime[j]=1;
}
}
}
prime[1]=1;
}
int min(int x,int y)
{
if(x>y)
return y;
else
return x;
}
int main()
{
int t,city;
__int64 need;
int exist;
int n[1000];
int i,j,x,y,c,k;
dabiao();
scanf("%d",&t);
while(t--)
{
scanf("%d",&city);
for(i=1;i<=city;i++)
{
set[i]=i;
scanf("%d",&n[i]);
}
k=0;
for(i=1;i<=city;i++)
{
for(j=i+1;j<=city;j++)
{
if(!prime[n[i]]||!prime[n[j]]||!prime[n[i]+n[j]])//可以连通 不能连通不记录
{
num[k].start=i;
num[k].end=j;
num[k].cost=min(min(n[i],n[j]),abs(n[i]-n[j]));
k++;
}
}
}
sort(num,num+k,cmp);
need=0;
for(i=0;i<k;i++)
{
if(find(num[i].start)!=find(num[i].end))
{
merge(num[i].start,num[i].end);
need+=num[i].cost;
}
}
exist=0;
for(i=1;i<=city;i++)
{
if(set[i]==i)
exist++;
if(exist>1)
break;
}
if(exist>1)
printf("-1\n");
else
printf("%I64d\n",need);
}
return 0;
}
prime:
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<string.h>
#define INF 0x3f3f3f
#define max 600+50
int map[max][max],visit[max],low[max];
int judge[1000000+1];
int city;
void prime()
{
int i,j,next;
int min,mincost=0;
for(i=1;i<=city;i++)
{
visit[i]=0;
low[i]=map[1][i];
}
visit[1]=1;
for(i=2;i<=city;i++)
{
min=INF;
next=1;
for(j=1;j<=city;j++)
{
if(!visit[j]&&min>low[j])
{
min=low[j];
next=j;
}
}
if(min==INF)
{
printf("-1\n");
return ;
}
visit[next]=1;
mincost+=min;
for(j=1;j<=city;j++)
{
if(!visit[j]&&map[next][j]<low[j])
low[j]=map[next][j];
}
}
printf("%d\n",mincost);
}
void dabiao()
{
int i,j;
memset(judge,0,sizeof(judge));
for(i=2;i<1000000+1;i++)
{
if(!judge[i])
{
for(j=2*i;j<1000000+1;j+=i)
judge[j]=1;
}
}
judge[1]=1;
}
int M(int x,int y)
{
if(x>y)
return y;
else
return x;
}
int main()
{
int t,i,j,x,y,c;
int n[max];
dabiao();
scanf("%d",&t);
while(t--)
{
scanf("%d",&city);
for(i=1;i<=city;i++)
{
scanf("%d",&n[i]);
for(j=1;j<=city;j++)
{
if(i==j)
map[i][j]=0;
else
map[i][j]=INF;
}
}
for(i=1;i<=city;i++)
{
for(j=i+1;j<=city;j++)
{
if(!judge[n[i]]||!judge[n[j]]||!judge[n[i]+n[j]])
{
map[i][j]=map[j][i]=M(M(n[i],n[j]),abs(n[i]-n[j]));
}
}
}
prime();
}
return 0;
}