zoukankan      html  css  js  c++  java
  • hdu 4081 Qin Shi Huang's National Road System

    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
    ",maxn);
    214     }
    215 
    216     return 0;
    217 }
  • 相关阅读:
    day12——Python高阶函数及匿名函数
    day11——Python函数的一般形式、函数的参数
    day10——Python file操作
    day9——Python复习
    day8——Python if,while,for
    day7——Python的帮助
    day6——Python数据类型
    sqlserver执行sql文件命令(sqlcmd)
    数据库快照、游标、锁
    Linux 下根据进程名kill进程
  • 原文地址:https://www.cnblogs.com/kickit/p/7172990.html
Copyright © 2011-2022 走看看