hdu 2682 Tree kruskal+并查集
Tree
Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2333 Accepted Submission(s): 710
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+最小生成树,模板题
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<queue> 5 #include<cmath> 6 #define MAX_N 1000005 7 8 using namespace std; 9 10 int n,m; 11 int par[MAX_N]; 12 int num[MAX_N]; 13 14 struct node 15 { 16 int a,b,va; 17 }edge[MAX_N]; 18 bool cmp(node a,node b) 19 { 20 return a.va<b.va; 21 } 22 int su(int a) 23 { 24 int flag=1; 25 for(int i = 2; i <= sqrt(a)&&flag; i++) 26 { 27 if(a%i==0) 28 flag=0; 29 } 30 if(a==1) 31 flag=0; 32 return flag; 33 } 34 int ffind(int x) 35 { 36 if(x==par[x]) 37 return x; 38 else 39 return par[x]=ffind(par[x]); 40 } 41 bool same(int x,int y) 42 { 43 return ffind(x)==ffind(y); 44 } 45 void mix(int x,int y) 46 { 47 x=ffind(x); 48 y=ffind(y); 49 if(x!=y) 50 par[x]=y; 51 } 52 int kruskal() 53 { 54 sort(edge,edge+m,cmp); 55 int ans=0,sum=0; 56 for(int i = 0; i < m; i++) 57 { 58 if(!same(edge[i].a,edge[i].b)) 59 { 60 mix(edge[i].a,edge[i].b); 61 sum+=edge[i].va; 62 ans++; 63 } 64 } 65 if(ans==n-1) 66 return sum; 67 else 68 return -1; 69 70 } 71 int main() 72 { 73 int t; 74 scanf("%d",&t); 75 while(t--) 76 { 77 scanf("%d",&n); 78 for(int i = 0; i <= n; i++) 79 par[i]=i; 80 for(int i = 1; i <= n; i++) 81 scanf("%d",&num[i]); 82 m=0; 83 for(int i = 1; i <= n; i++) 84 { 85 for(int j = i+1; j <= n; j++) 86 { 87 if(su(num[i])||su(num[j])||su(num[i]+num[j])) 88 { 89 edge[m].a=i; 90 edge[m].b=j; 91 edge[m++].va=min(min(num[i],num[j]),abs(num[i]-num[j])); 92 } 93 } 94 } 95 printf("%d\n",kruskal()); 96 } 97 return 0; 98 }