Tree
Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1704 Accepted Submission(s): 502
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题目大意:n个城市每个城市都有自己的幸福感,对于每两个城市A,B,对应的幸福感分别是VA,VB,如果满足VA或VB或VA+VB是素数,他们则是连通的,否则,嘿嘿,不连通。如果连通,其连通的代价是VA,VB,|VA-VB|.求将所有城市连通的最小值。虽然他加了素数判断这一外壳,但是它依然遮盖不了他是一道水题的事实。。。kruskal又来了。套模板的干活。我就不多解释了,直接上代码#include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #include<iostream> using namespace std; const int L=1000005,inf=1<<30,maxn=1005; struct node{int s,y,w;}edge[L]; int Fa[L],n,m,dot[L]; bool is[L]; void init(); void unite(int x,int y); void getPrime(); int Find(int x); int kruskal(); bool cmp(node a,node b); bool same(int x,int y); bool judge(int x,int y); int main() { int t; scanf("%d",&t); while(t--) { scanf("%d",&n);m=0; getPrime(); for(int i=1;i<=n;i++) scanf("%d",&dot[i]); for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) { if(judge(i,j)) { edge[m].s=i; edge[m].y=j; edge[m++].w=min(min(dot[i],dot[j]),abs(dot[i]-dot[j])); // printf("s=%d,y=%d,w=%d\n",i,j,abs(dot[i]-dot[j])); } } int ans=kruskal(); if(ans==-1) printf("-1\n"); else printf("%d\n",ans); } return 0; } void init()//初始化并查集 { for(int i=0;i<=n;i++) Fa[i]=i; } int Find(int x)//查询属于哪个集合,并直接拜“祖宗”为师 { if(Fa[x]==x) return x; else return Fa[x]=Find(Fa[x]); } void unite(int x,int y)//合并x,y两个元素 { x=Find(x);y=Find(y); if(x==y) return ; Fa[y]=x; } bool same(int x,int y)//【判断是否属于同个集合 { return Find(x)==Find(y); } bool cmp(node a,node b) { return a.w<b.w; } int kruskal() { sort(edge,edge+m,cmp); init(); int sum=0,cnt=0; for(int i=0;i<m;i++) { if(cnt==n-1) break; if(!same(edge[i].s,edge[i].y)) { unite(edge[i].s,edge[i].y); sum+=edge[i].w; cnt++; } } if(cnt!=n-1) return -1; return sum; } void getPrime() { fill(is,is+L,1); is[1]=0; // int np=0; for(int i=2;i<L;i++) if(is[i]) { // prime[++np]=i; for(int j=2*i;j<L;j+=i) is[j]=0; } } bool judge(int x,int y) { if(is[dot[x]]||is[dot[y]]||is[dot[x]+dot[y]]) return 1; return 0; }