码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 4081 Qin Shi Huang's National Road System (次小生成树)

时间:2015-06-04 15:08:08      阅读:132      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:

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

题目大意:

  有一天秦始皇想修n-1条路,把n个城市连起来,这个时候徐福突然出来说他可以用魔法变出来一条路,不用花费任何代价,秦始皇想让他变出来最长的路,徐福想变出对人们最有利的路(每条路对人们的利益等与这条路链接的两个城市的人数总和),最后他们一致决定选出要使A/B最大,A(徐福修的路给人们带来的利益),B(人工建的路的总长度)。

解题思路:

  求出来MST,然后枚举删除每一条边,求出最大即可。要求A/B最大,只需要A尽量大,B尽量小。B最小就是MST减去一条边,形成两个联通分支,再枚举能把这两个联通分支连起来并且可以使A最大的边,就可以得出答案。

 1 #include <cmath>
 2 #include <queue>
 3 #include <string>
 4 #include <cstdio>
 5 #include <cstring>
 6 #include <iostream>
 7 #include <algorithm>
 8 using namespace std;
 9 
10 const int maxn = 1010;
11 const int INF = 0x3f3f3f3f;
12 const double Exp = 1e-10;
13 
14 struct node
15 {
16     double x, y;
17     int p;
18     double length(node a)
19     {
20        return sqrt((a.x-x)*(a.x-x) + (a.y-y)*(a.y-y));
21     }
22 };
23 double cost[maxn+10][maxn+10], lowc[maxn+10], Max[maxn+10][maxn+10];
24 int vis[maxn+10], pre[maxn+10];
25 int n;
26 node stu[maxn+10];
27 double prim ()
28 {
29     int i, j;
30     double  sum = 0;
31     memset (vis, 0, sizeof(vis));
32     memset (Max, 0, sizeof(Max));
33     vis[1] = 1;
34     for (i=1; i<=n; i++)
35     {
36         pre[i] = 1;
37         lowc[i] = cost[1][i];
38     }
39     for (i=1; i<n; i++)
40     {
41         int p;
42         double mini = INF;
43         for (j=1; j<=n; j++)
44             if (!vis[j] && lowc[j] < mini)
45             {
46                 p = j;
47                 mini = lowc[j];
48             }
49         vis[p] = 1;
50         sum += mini;
51         for (j=1; j<=n; j++)
52         {
53             if (vis[j] && j!=p)
54                 Max[j][p] = Max[p][j] = max(Max[j][pre[p]], lowc[p]);
55             if (!vis[j] && lowc[j] > cost[j][p])
56                 {
57                     lowc[j] = cost[j][p];
58                     pre[j] = p;
59                 }
60         }
61     }
62     return sum;
63 }
64 void smst (double sum)
65 {//枚举删除,求最大解
66     double num = 0;
67     for (int i=1; i<=n; i++)
68         for (int j=i+1; j<=n; j++)
69             {
70                 double A, B;
71                 A = stu[i].p + stu[j].p;
72                 B = sum - Max[i][j];
73                 num = max(num, A/B);
74             }
75     printf ("%.2lf\n", num);
76 }
77 int main ()
78 {
79     int t;
80 
81     scanf ("%d", &t);
82     while (t --)
83     {
84         scanf ("%d", &n);
85         for (int i=1; i<=n; i++)
86         {
87             scanf ("%lf %lf %d", &stu[i].x, &stu[i].y, &stu[i].p);
88             for (int j=1; j<i; j++)
89                     cost[i][j] = cost[j][i] = stu[i].length(stu[j]);
90             cost[i][i] = 0;
91         }
92         double num = prim ();
93         smst (num);
94     }
95     return 0;
96 }

 

hdu 4081 Qin Shi Huang's National Road System (次小生成树)

标签:

原文地址:http://www.cnblogs.com/alihenaixiao/p/4551580.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!