Dream Team(最小生成树)

Input file: dream.in

Output file: standard output

Balloon Color: Pink

Before the World Cup, we would like to form the ultimate dream team. The team that will win against all teams. We have a big group of the top N players in the world, where each player has a number representing his skill level. Two players i and j with skill levels ai and aj have a compatibility of passing the ball between each other; this compatibility level is measured by the greatest common divisor of their skill levels (i.e. compatibility(i, j) = gcd(ai , aj )). We would like to decide a strategy that connects all the players of the dream team with a tree of connections between the players. If two players are directly connected in the chosen strategy, then they will pass the ball between each others during the matches, with the compatibility level between them. The compatibility of the strategy is the sum of the compatibility levels of its connections. What is the maximum total compatibility of the chosen strategy that connects all players?

Input

The first line of the input contains a single integer 1 ≤ T ≤ 50 the number of test cases. Each test case consists of one line that contains N + 1 space separated integers; the first integer is N, followed by the skill levels a1, · · · , an; where 1 ≤ N ≤ 105 and 1 ≤ ai ≤ 105 for all i.

Output

For each test case, print a single line displaying the case number and the maximum compatibility of the dream team’s strategy.

Example

dream.in

2

2 3 6

5 5 6 7 10 21

standard output

Case 1: 3

Case 2: 17

Note

In the second test case we connect the players 3−5 with compatibility 7, players 1−4 with compatibility 5, players 2−5 with compatibility 3 and players 2−4 with compatibility 2; therefore the total compatibility of the dream team’s strategy is 17.

 

从样例分析可知,从大到小一直找最大的最大公约数,即可得到答案

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 const int maxn = 1e6 + 50;
 6 int pre[maxn];
 7 
 8 vector<int> ve[maxn];
 9 
10 int Find(int x)
11 {
12     if(pre[x] == x) return x;
13     else return pre[x] = Find(pre[x]);
14 }
15 
16 int main()
17 {
18     freopen("dream.in", "r", stdin);
19     int t, i, j, a, b, x, k;
20     long long sum;
21     cin >> t;
22     k = 1;
23     while(t--)
24     {
25         int n;
26         cin >> n;
27         for(i=1;i<=1e5;i++)
28         {
29             pre[i] = i;
30             ve[i].clear();
31         }
32         for(i=1;i<=n;i++)
33         {
34 
35             cin >> x;
36             for(j=1;j<=x;j++)
37             {
38                 if(x % j == 0)
39                 {
40                     ve[j].push_back(i);
41                 }
42             }
43         }
44         sum = 0;
45         for(i=1e5; i>=1;i--)
46         {
47             if(ve[i].empty()) continue;
48             for(j=0; j<ve[i].size()-1; j++)
49             {
50                 a = Find(ve[i][j]);
51                 b = Find(ve[i][j+1]);
52                 if(a!=b)
53                 {
54                     pre[b] = a;
55                     sum += i;
56                 }
57             }
58         }
59         cout << "Case " << k++ << ": ";
60         cout << sum << endl;
61     }
62     return 0;
63 }

 

posted @ 2019-08-15 17:22  Xxiaoyu  阅读(209)  评论(0编辑  收藏  举报