最小生成树

hdu 2682 最小生成树

分类: 练习 152人阅读 评论(0) 收藏 举报
ACM C 算法 图论 最小生成树

http://acm.hdu.edu.cn/showproblem.php?pid=2682

题目大意:T组测试实例,每组实例有n个城市,每个城市有一个幸福指数V;如果 Va 或 Vb 或 Va+Vb 是素数的话,两个城市可以连接起来;将两个城市连接起来所需的花费为min(min(Va,Vb),|Va-Vb|);如果所有的城市都能连接起来的话输出最小花费,否则输出“-1”;

[cpp] view plain copy print ?
  1. #include<iostream>
  2. #include<stdio.h>
  3. #include<string.h>
  4. #include<stdlib.h>
  5. #include<math.h>
  6. #include<algorithm>
  7. #define MAX 1000006
  8. #define min(a,b) ((a)<(b)?(a):(b))
  9. using namespace std;
  10. int prime[MAX];
  11. int set[606];
  12. struct node
  13. {
  14. int a,b,len;
  15. }map[180000];
  16. int cmp(const void* a,const void*b)
  17. {
  18. return (*(node*)a).len-(*(node*)b).len;
  19. }
  20. //并查集
  21. int find(int x)
  22. {
  23. if(set[x]!=x){
  24. set[x]=find(set[x]);
  25. }
  26. return set[x];
  27. }
  28. int Union(int a,int b)
  29. {
  30. int x=find(a);
  31. int y=find(b);
  32. if(x==y)
  33. return 0;
  34. set[x]=y;
  35. return 1;
  36. }
  37. int main()
  38. {
  39. int T,n,i,j,k,temp,cnt,cost;
  40. //筛选法求素数
  41. memset(prime,0,sizeof(prime));
  42. prime[0]=1;
  43. prime[1]=1;
  44. for(i=2;i<MAX;i++){
  45. if(prime[i]==0){
  46. for(j=2;j<MAX;j++){
  47. temp=i*j;
  48. if(temp>MAX)break;
  49. prime[temp]=1;
  50. }
  51. }
  52. }
  53. scanf("%d",&T);
  54. while(T--){
  55. scanf("%d",&n);
  56. for(i=0;i<n;i++){
  57. scanf("%d",&set[i]);
  58. }
  59. //建图
  60. for(i=0,k=0;i<n;i++){
  61. for(j=i+1;j<n;j++){
  62. if(prime[set[i]]==0 || prime[set[j]]==0 || prime[set[i]+set[j]]==0){
  63. map[k].a=i;
  64. map[k].b=j;
  65. map[k++].len=min(min(set[i],set[j]),abs(set[i]-set[j]));
  66. }
  67. }
  68. }
  69. qsort(map,k,sizeof(map[0]),cmp);
  70. for(i=0;i<n;i++){
  71. set[i]=i;
  72. }
  73. for(i=0,cnt=0,cost=0;i<k;i++){
  74. if(Union(map[i].a,map[i].b)==1){
  75. cost+=map[i].len;
  76. cnt++;
  77. }
  78. }
  79. if(cnt==(n-1))
  80. printf("%d\n",cost);
  81. else
  82. printf("-1\n");
  83. }
  84. return 0;
  85. }

你可能感兴趣的:(练习)