zoukankan      html  css  js  c++  java
  • LA 5713 秦始皇修路

    https://vjudge.net/problem/UVALive-5713

    题意:

    秦朝有n个城市,需要修建一些道路使得任意两个城市之间都可以连通。道士徐福声称他可以用法术修路,不花钱,也不用劳动力,但只能修一条路,因此需要慎重选择用法术修哪一条路。秦始皇不仅希望其他道路的总长度B尽量短(这样可以节省劳动力),还希望法术连接的两个城市的人口之和A尽量大,因此下令寻找一个使得A/B最大的方案。你的任务是找到这个方案。

    任意两个城市之间都可以修路,长度为两个城市之间的欧几里德距离。

    思路:

    先计算出最小生成树,之后用法术修的路肯定在最小生成树当中,那么之后我们就可以枚举边u-v。

    当然,需要预处理,像最小生成树一样,计算出u和v之间唯一路径上的最大权maxcost[u][v]。

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstdio>
      4 #include<cstring>
      5 #include<string>
      6 #include<vector>
      7 #include<queue>
      8 #include<cmath>
      9 #include<map>
     10 using namespace std;
     11 typedef long long LL;
     12 const int maxn=1000+5;
     13 
     14 struct node
     15 {
     16     int u,v;
     17     double dist;
     18     bool operator < (const node& rhs) const
     19     {
     20         return dist<rhs.dist;
     21     }
     22 }edge[maxn*maxn];
     23 
     24 int n;
     25 int cnt;
     26 int p[maxn];
     27 int x[maxn],y[maxn];
     28 int num[maxn];
     29 vector<int> g[maxn];   //存储最小生成树中结点u的邻接结点
     30 vector<double> c[maxn];  //c[u][i]表示结点u和和结点g[u][i]之间的边权
     31 
     32 double maxcost[maxn][maxn];  //u,v两点之间的最大边权
     33 vector<int> nodes;
     34 
     35 int find(int x)
     36 {
     37     return x==p[x]?x:p[x]=find(p[x]);
     38 }
     39 
     40 double MST()
     41 {
     42     sort(edge,edge+cnt);
     43     int tot_edge=0;
     44     double tot_q=0;
     45     for(int i=0;i<cnt;i++)
     46     {
     47         int x=edge[i].u, y=edge[i].v;
     48         int u=find(x), v=find(y);
     49         if(u!=v)
     50         {
     51             p[u]=v;
     52             g[x].push_back(y); c[x].push_back(edge[i].dist);
     53             g[y].push_back(x); c[y].push_back(edge[i].dist);
     54             tot_q+=edge[i].dist;
     55             if(++tot_edge==n-1)  break;
     56         }
     57     }
     58     return tot_q;
     59 }
     60 
     61 void dfs(int u,int fa,double cost)  //无根树转有根树,计算出u,v两点之间路径的最大边权
     62 {
     63     for(int i=0;i<nodes.size();i++)
     64     {
     65         int x=nodes[i];
     66         maxcost[x][u]=maxcost[u][x]=max(maxcost[x][fa],cost);   //更新之前的结点与新加入的结点之前的最大边权
     67     }
     68     nodes.push_back(u);
     69     for(int i=0;i<g[u].size();i++)
     70     {
     71         int v=g[u][i];
     72         if(v!=fa) dfs(v,u,c[u][i]);
     73     }
     74 }
     75 
     76 int main()
     77 {
     78     //freopen("D:\input.txt","r",stdin);
     79     int T;
     80     scanf("%d",&T);
     81     while(T--)
     82     {
     83         cnt=0;
     84         scanf("%d",&n);
     85         for(int i=0;i<n;i++)  {p[i]=i; g[i].clear(); c[i].clear();}
     86         for(int i=0;i<n;i++)
     87         {
     88             scanf("%d%d%d",&x[i],&y[i],&num[i]);
     89             for(int j=0;j<i;j++)
     90             {
     91                 edge[cnt].u=j;
     92                 edge[cnt].v=i;
     93                 edge[cnt].dist=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
     94                 cnt++;
     95             }
     96         }
     97         double tot=MST();
     98         memset(maxcost,0,sizeof(maxcost));
     99         nodes.clear();
    100         dfs(0,-1,0);
    101         double ans=-1;
    102         for(int i=0;i<n;i++)
    103         {
    104             for(int j=i+1;j<n;j++)
    105             {
    106                 ans=max(ans,(num[i]+num[j])/(tot-maxcost[i][j]));
    107             }
    108         }
    109         printf("%.2lf
    ",ans);
    110     }
    111     return 0;
    112 }
  • 相关阅读:
    libmegjb.so加载问题调试和分析
    art虚拟机启动问题分析
    高通发布骁龙808六核/810八核64位芯片
    pivotx的entry和page内容里的日期格式修改
    dlmalloc(Android bionic C库的malloc实现)简介
    dojo分析之declare接口
    零基础搞懂智能机之手机参数怎么看
    Google one联合联发科,国内低端智能机方案怎么办?
    自己搭建云存储(WIFI路由器上接硬盘)
    数据结构目录(浙大)
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/6872395.html
Copyright © 2011-2022 走看看