您的位置:首页 > 其它

hdoj 2682 Tree(最小生成树+打表)

2015-11-23 15:53 483 查看


Tree

Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 2107    Accepted Submission(s): 610


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
建图比较难,其他比较模板! 代码: 库鲁斯卡尔:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
#define  N 1100
#define  INF  0x3f3f3f3f
int a
,prime[1000000+100],set
;

struct node
{
int strart;
int end;
int dist;
}num[370000];

bool cmp (node a,node b)
{
return a.dist<b.dist ;
}

void  dabiao()//打表,以免超时
{
int i,j;
memset(prime,0,sizeof(prime));
for(i=2;i<1000000+100;i++)
{
if(!prime[i])
for(j=2*i;j<1000000+100;j+=i)
prime[j]=1;
}
prime[1]=1;
}

int  find(int p)
{
int temp,child=p;
while(p!=set[p])
p=set[p];
while(child!=p)
{
temp=set[child];
set[child]=p;
child=temp;
}
return p;
}

void  merge(int x,int y)
{
int fx=find(x);
int fy=find(y);
if(fx!=fy)
set[fx]=fy;
}

int minxe(int  a,int b,int c)
{
if(a>b)
a=b;
if(a>c)
a=c;
return  a;
}

int main()
{
int t;
scanf("%d",&t);
dabiao();
while(t--)
{
int i,j,k=1,n,outcome=0;
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++)
{
num[k].strart =i;
num[k].end =j;
if(!prime[a[i]]||!prime[a[j]]||!prime[a[i]+a[j]])
{
num[k].dist=minxe(a[i],a[j],abs(a[i]-a[j]));
}
else
num[k].dist =INF;
k++;
}
sort(num,num+k,cmp);
for(i=1;i<=n;i++)
set[i]=i;
int flag=1;
for(i=1;i<k;i++)
{
if(find(num[i].strart )!=find(num[i].end ))
{
if(num[i].dist ==INF)
{
flag=0;
break;
}
outcome+=num[i].dist ;
merge(num[i].strart ,num[i].end );

}
}
if(!flag)
{
printf("-1\n");
continue;
}
if(outcome>=INF)
printf("-1\n");
else
printf("%d\n",outcome);
}
return  0;
}


普里姆:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#define  INF  0x3f3f3f
#define  N 1100
int a
,n;
int map

,prime[1000000+100];

void dabiao()//打表求素数
{
int i,j,k;
memset(prime,0,sizeof(prime));
for(i=2;i<1000000+100;i++)
{
if(!prime[i])
for(j=2*i;j<1000000+100;j+=i)
prime[j]=1;
}
prime[1]=1;
}

int min(int a,int  b,int  c)//求最小值
{
if(a>b)
a=b;
if(a>c)
a=c;
return  a;
}

void prim()//求最小树
{
int mincost,next=0,i,j,k,result=0;
int visit
,cost
;
memset(visit,0,sizeof(visit));
for(i=0;i<n;i++)
{
cost[i]=map[0][i];
}
visit[0]=1;
for(i=1;i<n;i++)
{
mincost=INF,next=0;
for(j=0;j<n;j++)
{
if(!visit[j]&&cost[j]<mincost)
{
mincost=cost[j];
next=j;
}
}
if(!next)
{
printf("-1\n");
return  ;
}
visit[next]=1;
result+=mincost;
for(j=0;j<n;j++)
{
if(!visit[j]&&cost[j]>map[next][j])
cost[j]=map[next][j];
}
}
if(result)
printf("%d\n",result);
else
printf("-1\n");
}

int main()
{
int t;
scanf("%d",&t);
dabiao();
while(t--)
{
int i,j,k;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
for(i=0;i<n;i++)
{
map[i][i]=0;
for(j=i+1;j<n;j++)
{
if(!prime[a[i]]||!prime[a[j]]||!prime[a[i]+a[j]])
map[i][j]=map[j][i]=min(a[i],a[j],abs(a[i]-a[j]));
else
map[i][j]=map[j][i]=INF;
}
}

prim();
}
return  0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息