Tree HDOJ--2682

Tree

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


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
思路:由于题目对能相连的点有限制,必须将这些点处理,能相连的点合并到一个集合中,最后查看是否所有点都在一个集合里,若都在说明是一个连通图,存在最小生成树,否则图不连通,不存在最小花费。
AC代码:
 
  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<stdlib.h>
  4 int CityHappy[605],vis[605];
  5 int isprime[1000005],dist[605];
  6 int map[601][601],n;
  7 int father[605],depth[605];
  8 void init_B()
  9 {
 10     int i;
 11     for(i = 1;i <= n;i ++)
 12     {
 13         father[i] = i;
 14         depth[i] = 0;
 15     }
 16 }
 17 
 18 int find(int x)
 19 {
 20     if(x == father[x])
 21         return x;
 22     return father[x] = find(father[x]);
 23 }
 24 
 25 void unit(int x,int y)
 26 {
 27     x = find(x);
 28     y = find(y);
 29     if(x == y)
 30         return ;
 31     if(depth[x] > depth[y])
 32         father[y] = x;
 33     else
 34     {
 35         if(depth[x] < depth[y])
 36             father[x] = y;
 37         else
 38         {
 39             father[x] = y;
 40             depth[y]++;
 41         }
 42     }
 43 }
 44 
 45 void prime()
 46 {
 47     int i,j;
 48     isprime[0] = isprime[1] = 1;
 49     for(i = 2;i <= 1e6;i ++)
 50     {
 51         if(!isprime[i])
 52         {
 53             for(j = i << 1;j <= 1e6;j += i)
 54                 isprime[j] = 1;
 55         }
 56     }
 57 }
 58 
 59 int judge(int a,int b)
 60 {
 61     if(!isprime[a] || !isprime[b])
 62         return 1;
 63     if(!isprime[a+b])
 64         return 1;
 65     return 0;
 66 }
 67 
 68 int min(int a,int b)
 69 {
 70     return a < b?a:b;
 71 }
 72 
 73 void opration()
 74 {
 75     int i,j,a,b;
 76     init_B();
 77     for(i = 1;i <= n;i ++)
 78     {
 79         for(j = 1;j <= n;j ++)
 80         {
 81             if(i != j)
 82             {
 83                 a = CityHappy[i];
 84                 b = CityHappy[j];
 85                 if(judge(a,b))
 86                 {
 87                     map[i][j] = min(min(a,b),abs(a-b));
 88                     map[j][i] = map[i][j];
 89                     unit(i,j);
 90                 }
 91                 else
 92                     map[i][j] = map[j][i] = 1 << 30;
 93             }
 94         }
 95     }
 96 }
 97 
 98 void init()
 99 {
100     int i;
101     memset(vis,0,sizeof(vis));
102     for(i = 1;i <= n;i ++)
103         dist[i] = map[1][i];
104 }
105 
106 int main()
107 {
108     int t,i,j,k,cnt,min,sum;
109     scanf("%d",&t);
110     prime();
111     while(t--)
112     {
113         sum = cnt = 0;
114         scanf("%d",&n);
115         for(i = 1;i <= n;i ++)
116             scanf("%d",&CityHappy[i]);
117         opration();
118         init();
119         for(i = 1;i <= n;i ++)
120         {
121             if(i == find(i))
122                 cnt++;
123             if(cnt == 2)
124                 break;
125         }
126         if(cnt == 2)
127         {
128             printf("-1\n");
129             continue ;
130         }
131         for(i = 0;i < n;i ++)
132         {
133             min = 1 << 30;
134             for(j = 1;j <= n;j ++)
135             {
136                 if(!vis[j] && min > dist[j])
137                 {
138                     min = dist[j];
139                     k = j;
140                 }
141             }
142             vis[k] = 1;
143             if(min != 1 << 30)
144                 sum += min;
145             for(j = 1;j <= n;j ++)
146             {
147                 if(!vis[j] && dist[j] > map[k][j])
148                     dist[j] = map[k][j];
149             }
150         }
151         printf("%d\n",sum);
152     }
153     return 0;
154 }

 

 

 

posted on 2013-10-18 16:11  ~Love()  阅读(227)  评论(0编辑  收藏  举报

导航