HDU2724 Tree【最小生成树】

来源:互联网 发布:程序员应该读的书籍 编辑:程序博客网 时间:2024/05/29 14:21

题目大意:

有N个城市,每个城市有一个幸福值,如果两个城市A、B的幸福值分别为VA、VB,如果VA是

数,或者VB是素数,又或者VA+VB是素数,则城市A和B就能连接一条路,建路的所用花费

Min(Min(VA , VB),|VA-VB|)。

问:现在想要建几条路,使得能够连接所有的城市,所需要建设的最少路程和是多少?


思路:

就是求最小生成树,先用素数筛选法将素数打表,然后根据题意建边。最后就是用Prim模板求

最小生成树就行了。


AC代码:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #include<iostream>  
  2. #include<algorithm>  
  3. #include<cstdio>  
  4. #include<cstring>  
  5. using namespace std;  
  6. const int MAXN = 660;  
  7. const int INF = 0xffffff0;  
  8.   
  9. int vis[MAXN],low[MAXN],Map[MAXN][MAXN],A[MAXN];  
  10. int prim(int n)  
  11. {  
  12.     int pos,Min,result = 0;  
  13.     memset(vis,0,sizeof(vis));  
  14.   
  15.     vis[1] = 1;  
  16.     pos = 1;  
  17.   
  18.     for(int i = 1; i <= n; i++)  
  19.         if(i != pos)  
  20.             low[i] = Map[pos][i];  
  21.   
  22.     for(int i = 1; i < n; i++)  
  23.     {  
  24.         Min = INF;  
  25.         for(int j = 1; j <= n; j++)  
  26.         {  
  27.             if(vis[j]==0 && Min > low[j])  
  28.             {  
  29.                 Min = low[j];  
  30.                 pos = j;  
  31.             }  
  32.         }  
  33.   
  34.         result += Min;  
  35.         vis[pos] = 1;  
  36.   
  37.         for(int j = 1; j <= n; j++)  
  38.         {  
  39.             if(vis[j]==0 && low[j] > Map[pos][j])  
  40.             {  
  41.                 low[j] = Map[pos][j];  
  42.             }  
  43.         }  
  44.     }  
  45.   
  46.     return result;  
  47. }  
  48.   
  49. bool Prime[1000100];  
  50.   
  51. void IsPrime()  
  52. {  
  53.     for(int i = 2; i <= 1000000; ++i)  
  54.         Prime[i] = true;  
  55.     for(int i = 2; i <= 1000000; ++i)  
  56.     {  
  57.         if(Prime[i])  
  58.         {  
  59.             for(int j = i+i; j <= 1000000; j += i)  
  60.                 Prime[j] = false;  
  61.         }  
  62.     }  
  63. }  
  64.   
  65. int father[MAXN];  
  66.   
  67. int find(int x)  
  68. {  
  69.     if(x == father[x])  
  70.         return father[x];  
  71.     else  
  72.         return father[x] = find(father[x]);  
  73. }  
  74.   
  75. int main()  
  76. {  
  77.     int T,N;  
  78.     scanf("%d",&T);  
  79.     IsPrime();  
  80.     while(T--)  
  81.     {  
  82.         scanf("%d",&N);  
  83.         for(int i = 1; i <= N; ++i)  
  84.             for(int j = 1; j <= N; ++j)  
  85.                 Map[i][j] = INF;  
  86.         for(int i = 1; i <= N; ++i)  
  87.             scanf("%d",&A[i]);  
  88.   
  89.         for(int i = 1; i <= N; ++i)  
  90.             father[i] = i;  
  91.   
  92.         for(int i = 1; i <= N; ++i)  
  93.         {  
  94.             for(int j = i+1; j <= N; ++j)  
  95.             {  
  96.                 if(Prime[A[i]] || Prime[A[j]] || Prime[A[i]+A[j]])  
  97.                 {  
  98.                     int x = find(i);  
  99.                     int y = find(j);  
  100.                     if(x != y)  
  101.                         father[x] = y;  
  102.                     Map[i][j] = Map[j][i] = min(min(A[i],A[j]),abs(A[i]-A[j]));  
  103.                 }  
  104.             }  
  105.         }  
  106.         int flag = 1;  
  107.         for(int i = 1; i <= N; ++i)  
  108.         {  
  109.             if(find(i) != find(1))  
  110.                 flag = 0;  
  111.         }  
  112.         if(flag)  
  113.             printf("%d\n",prim(N));  
  114.         else  
  115.             printf("-1\n");  
  116.     }  
  117.   
  118.     return 0;  
  119. }  
0 0
原创粉丝点击