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

HDU 4081 Qin Shi Huang's National Road System

时间:2017-07-14 23:04:48      阅读:185      评论:0      收藏:0      [点我收藏+]

标签:logs   blog   https   can   int   博文   最大   print   clu   

https://vjudge.net/problem/HDU-4081

题意:

秦始皇想要修长城,修成生成树的样子,这是一个大师出现了,他说他可以不耗费人力修出一条路来。他们的目的很不一样,神特么有分歧,最后他们达成了一个协议,假设一个城市的人口为a。那么最后不耗费人力修的那条路所相连的两个城市的人力之和A与修路花费的人力B之比 A/B最大,并且输出最大值。

思路:

枚举去掉每一条边。

首先求出最小生成树,对于最小生成树中的每一条边,如果这条边不花费人力,那么直接计算A和B就可以了。

那么问题是如果选择的边不在最小生成树中的话,应该怎么办。为了形成生成树,肯定要将最小生成树生成树中的边去掉,又为了保持边的权值之和是最小的,所以自然想到了次小生成树,用到了maxn[u][v]那个数组,所以就将maxn[u][v]减去进行比较就行了。maxn[u][v]的求法请见次小生成树学习的博文。

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <algorithm>
  4 #include <math.h>
  5 #include <vector>
  6 #include <queue>
  7 using namespace std;
  8 
  9 struct node
 10 {
 11     int x,y;
 12     double len;
 13 } a[1000005];
 14 
 15 struct com
 16 {
 17     int id;
 18     double dis;
 19 };
 20 
 21 int h[1005],z[1005],p[1005];
 22 int par[1005];
 23 bool v[1000005];
 24 double ma[1005][1005];
 25 bool vis[1005];
 26 vector<node> no[1005];
 27 
 28 bool cmp(node aa,node bb)
 29 {
 30     if (aa.len == bb.len)
 31     {
 32         double t1 = p[aa.x] + p[aa.y];
 33         double t2 = p[bb.x] + p[bb.y];
 34 
 35         return t2 < t1;
 36     }
 37 
 38     return aa.len < bb.len;
 39 }
 40 
 41 void init(int n)
 42 {
 43     for (int i = 0;i < n;i++)
 44         par[i] = i;
 45 }
 46 
 47 int fin(int x)
 48 {
 49     if (x == par[x]) return x;
 50     else return par[x] = fin(par[x]);
 51 }
 52 
 53 void unit(int x,int y)
 54 {
 55     x = fin(x);
 56     y = fin(y);
 57 
 58     if (x != y) par[x] = y;
 59 }
 60 
 61 double cal(int i,int j)
 62 {
 63     double dis1 = 1.0 * (h[i] - h[j]) * (h[i] - h[j]);
 64     double dis2 = 1.0 * (z[i] - z[j]) * (z[i] - z[j]);
 65 
 66     return sqrt(dis1 + dis2);
 67 }
 68 
 69 void adde(int x,int y,double dis)
 70 {
 71     node t;
 72 
 73     t.x = x;
 74     t.y = y;
 75     t.len = dis;
 76 
 77     no[x].push_back(t);
 78 }
 79 
 80 void bfs(int k)
 81 {
 82     memset(vis,0,sizeof(vis));
 83 
 84     com now,nex;
 85 
 86     queue<com> qq;
 87 
 88     while (!qq.empty()) qq.pop();
 89 
 90     now.id = k;now.dis = 0;
 91     vis[now.id] = 1;
 92 
 93     qq.push(now);
 94 
 95     while (!qq.empty())
 96     {
 97         com tc = qq.front();qq.pop();
 98 
 99         int tx = tc.id;
100         double maxn = tc.dis;
101 
102         for (int i = 0;i < no[tx].size();i++)
103         {
104             node tmp = no[tx][i];
105             int ty = tmp.y;
106             double tmaxn = tmp.len;
107 
108             if (!vis[ty])
109             {
110                 vis[ty] = 1;
111                 nex.id = ty;
112                 nex.dis = tmaxn;
113 
114                 if (maxn > tmaxn) nex.dis = maxn;
115 
116                 ma[k][ty] = nex.dis;
117 
118                 qq.push(nex);
119             }
120         }
121     }
122 }
123 
124 int main()
125 {
126     int t;
127 
128     scanf("%d",&t);
129 
130     while (t--)
131     {
132         int n;
133 
134         scanf("%d",&n);
135 
136         init(n);
137         memset(a,0,sizeof(a));
138         memset(v,0,sizeof(v));
139         memset(no,0,sizeof(no));
140 
141         for (int i = 0;i < n;i++)
142         {
143             scanf("%d%d%d",&h[i],&z[i],&p[i]);
144         }
145 
146         int cnt = 0;
147 
148         for (int i = 0;i < n;i++)
149             for (int j = i + 1;j < n;j++)
150         {
151             a[cnt].x = i;a[cnt].y = j;
152             a[cnt].len  = cal(i,j);
153             cnt++;
154         }
155 
156         double es = 0;
157 
158         sort(a,a+cnt,cmp);
159 
160         for (int i = 0;i < cnt;i++)
161         {
162             int x = a[i].x,y = a[i].y;
163 
164             if (fin(x) == fin(y)) continue;
165 
166             unit(x,y);
167 
168             v[i] = 1;
169 
170             adde(x,y,a[i].len);
171             adde(y,x,a[i].len);
172 
173             es += a[i].len;
174         }
175 
176         double maxn = 0;
177 
178         for (int i = 1;i <= n;i++)
179         {
180             bfs(i);
181         }
182 
183         for (int i = 0;i < cnt;i++)
184         {
185             if (v[i])
186             {
187                 double ns = 0;
188                 int x = a[i].x,y = a[i].y;
189 
190                 ns += p[x];ns += p[y];
191 
192                 es -= a[i].len;
193 
194                 if (ns / es > maxn) maxn = ns / es;
195 
196                 es += a[i].len;
197             }
198             else
199             {
200                 double ns = 0;
201                 int x = a[i].x,y = a[i].y;
202 
203                 ns += p[x];ns += p[y];
204 
205                 es -= ma[x][y];
206 
207                 if (ns / es > maxn) maxn = ns / es;
208 
209                 es += ma[x][y];
210             }
211         }
212 
213         printf("%.2f\n",maxn);
214     }
215 
216     return 0;
217 }

 

HDU 4081 Qin Shi Huang's National Road System

标签:logs   blog   https   can   int   博文   最大   print   clu   

原文地址:http://www.cnblogs.com/kickit/p/7172990.html

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