Tree(并查集)

Tree

Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1771    Accepted Submission(s): 517


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<algorithm>
using namespace std;
#define M 1000010
int notprime[M];
int s[1000010];
int f[M]; 
struct node{
	int a;
	int b;
	int c;
}p[1000010];
void fun(){
	int i,j;
	memset(notprime,0,sizeof(notprime));
	notprime[1]=1;
	for(i=2;2*i<M;i++){
		if(!notprime[i]){
			for(j=2*i;j<M;j+=i)
			notprime[j]=1;
		}
	}
}
bool cmp(node x,node y){
	return x.c<y.c;
}
int find(int x){
	return x==f[x]?x:f[x]=find(f[x]);
}
int bin(int x1,int x2,int x3){
	int t1,t2,x4=0;
	t1=find(x1);
	t2=find(x2);
	if(t1!=t2){
		f[t1]=t2;
		x4+=x3;
	}
	return x4;
}
int main(){
	int T;
	fun();
	scanf("%d",&T);
	while(T--){
		int n,m;
		int i,j,k=0;
		memset(p,0,sizeof(p));
		scanf("%d",&n);
		for(i=1;i<=n;i++){
			f[i]=i;
			scanf("%d",&s[i]);
		}
		for(i=1;i<=n;i++){
		   // f[i]=i;
		//	scanf("%d",&s[i]);//不能这样写。会超时的 
			for(j=1;j<i;j++){
				if(!notprime[s[i]]||!notprime[s[j]]||!notprime[s[i]+s[j]])
				{
					p[k].a=i;
					p[k].b=j;
				//	f[i]=j;
					p[k++].c=min(min(s[i],s[j]),abs(s[i]-s[j]));
				}
			}
		}
		sort(p,p+k,cmp);
//		for(i=0;i<k;i++){
//			printf("%d %d %d\n",p[i].a,p[i].b,p[i].c);
//		}
		int sum=0;
		for(i=0;i<k;i++){
		 if(find(p[i].a)!=find(p[i].b))
		 sum+=bin(p[i].a,p[i].b,p[i].c);
	    }
	    int l=0;
	   for(i=1;i<=n;i++){
	   	if(f[i]==i)
	   	l++;
	   }
	   if(l>1)
	   printf("-1\n");
	   else
	   printf("%d\n",sum);
	} 
} 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值