题目链接:传送门

题意:

有n坐城市,知道每坐城市的坐标和人口。如今要在全部城市之间修路,保证每一个城市都能相连,而且保证A/B 最大。全部路径的花费和最小,A是某条路i两端城市人口的和,B表示除路i以外全部路的花费的和(路径i的花费为0).

分析:

先求一棵最小生成树,然后枚举每一条最小生成树上的边,删掉后变成两个生成树。然后找两个集合中点权最大的两

个连接起来。这两个点中必定有权值最大的那个点。所以直接从权值最大的点開始dfs。

  为了使A/B的值最大,则A尽可能大,B尽可能小。所以B中的边一定是MST上去掉一条边后的剩余全部边。首先用O(N^2)算出

  MST,然后依次枚举。删去MST上的每一条边。MST变成两棵树T1和T2,然后在剩余的边(即不在MST上的边),以及这条删

  去的边中找到该边的两点的权值和最大以及可以连接T1和T2的边。A=删去边后的替换边的两点的权值和,B=删去该边后的MST

  的值。求A/B最大。

则A尽可能大,A各自是T1和T2中最大的两个点,则全部点中权值最大的点一定在A中。由此在MST上从权值

  最大的点作为root。開始dfs。递归求出子树中的每一个最大的点以及求出A/B的比值,求出最大。

分析转载自:传送门

我的理解。首先非常明显我们是须要求出最小生成树的,然后我们能够枚举边(u,v)中的边,非常明显枚举的边都会

与原来MST中的边形成一个环,由于这个边不在MST中,那么这个边的权值一定是大于MST中连接U,V的边的,因此

我们在这个环里去掉的应该是权值最大的边。

代码例如以下:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std; const int maxn = 1e3+10; const int inf = 1e9+10; struct point{
int x,y;
}a[maxn]; int head[maxn],par[maxn],peo[maxn]; bool vis[maxn]; int ip,mmax;
double ans ,mst; struct tree{
int u,v;
double w;
tree(){}
tree(int _u,int _v,double _w):u(_u),v(_v),w(_w){}
bool operator < (const struct tree &tmp)const{
return w<tmp.w;
}
}mp[maxn*maxn]; struct nod{
int to,next;
double w;
}edge[maxn*2]; double calu(point a,point b){
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
} void add(int u,int v,double w){
edge[ip].to=v;
edge[ip].w=w;
edge[ip].next=head[u];
head[u]=ip++;
} int find_par(int x){
if(x!=par[x]) return par[x]=find_par(par[x]);
return par[x];
} bool Union(int x,int y){
x=find_par(x);
y=find_par(y);
if(x!=y){
par[x]=y;
return true;
}
return false;
} void init(){
for(int i=0;i<maxn;i++) par[i]=i;
ip=mmax=0;
ans=mst=0;
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
} int dfs(int root){
vis[root]=1;
int peo_max=peo[root];
for(int i=head[root];i!=-1;i=edge[i].next){
int v=edge[i].to;
if(!vis[v]){
int tmp = dfs(v);
peo_max=max(peo_max,tmp);
ans=max(ans,(tmp+mmax)/(mst-edge[i].w));
}
}
return peo_max;
} int main(){
int t,n,root;
scanf("%d",&t);
while(t--){
init();
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d%d%d",&a[i].x,&a[i].y,&peo[i]);
if(peo[i]>mmax){
mmax=peo[i];
root=i;
}
}
int cnt = 0;
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
mp[cnt++]=tree(i,j,calu(a[i],a[j]));
}
}
sort(mp,mp+cnt);
for(int i=0;i<cnt;i++){
if(Union(mp[i].u,mp[i].v)){
mst+=mp[i].w;
add(mp[i].u,mp[i].v,mp[i].w);
add(mp[i].v,mp[i].u,mp[i].w);
}
}
dfs(root);
printf("%.2lf\n",ans);
}
return 0;
}

HDU 4081 Qin Shi Huang&#39;s National Road System(最小生成树/次小生成树)的更多相关文章

  1. HDU 4081 Qin Shi Huang&#39;s National Road System 最小生成树

    点击打开链接题目链接 Qin Shi Huang's National Road System Time Limit: 2000/1000 MS (Java/Others)    Memory Lim ...

  2. HDU4081 Qin Shi Huang&#39;s National Road System【prim最小生成树+枚举】

    先求出最小生成树,然后枚举树上的边,对于每条边"分别"找出这条割边形成的两个块中点权最大的两个 1.因为结果是A/B.A的变化会引起B的变化,两个制约.无法直接贪心出最大的A/B. ...

  3. HDU 4081 Qin Shi Huang's National Road System 最小生成树+倍增求LCA

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4081 Qin Shi Huang's National Road System Time Limit: ...

  4. HDU 4081 Qin Shi Huang's National Road System 次小生成树变种

    Qin Shi Huang's National Road System Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/3 ...

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

    Qin Shi Huang's National Road System Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/3 ...

  6. hdu 4081 Qin Shi Huang's National Road System (次小生成树的变形)

    题目:Qin Shi Huang's National Road System Qin Shi Huang's National Road System Time Limit: 2000/1000 M ...

  7. hdu 4081 Qin Shi Huang's National Road System 树的基本性质 or 次小生成树思想 难度:1

    During the Warring States Period of ancient China(476 BC to 221 BC), there were seven kingdoms in Ch ...

  8. HDU 4081—— Qin Shi Huang's National Road System——————【次小生成树、prim】

    Qin Shi Huang's National Road System Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/3 ...

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

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4081 题意:有n个城市,秦始皇要修用n-1条路把它们连起来,要求从任一点出发,都可以到达其它的任意点. ...

随机推荐

  1. innobackupex不停库的数据备份并恢复到别的服务器上【转】

    1.innobackupex原理: 备份原理 1).首先会开启一个后台检测进程,实时检测myql redo的变化,一旦发现redo中有新日志写入,立即将日志记入后台日志文件xtrabackup_log ...

  2. 搜索引擎ElasticSearchV5.4.2系列三之ES使用

    相关博文: 搜索引擎ElasticSearchV5.4.2系列一之ES介绍 搜索引擎ElasticSearchV5.4.2系列二之ElasticSearchV5.4.2+kibanaV5.4.2+x- ...

  3. jenkins执行构建任务报错之java.lang.NoSuchFieldError: DEFAULT_USER_SETTINGS_FILE

    在执行创建工作空间时候,创建不成功,出现错误?? ......... java.lang.NoSuchFieldError: DEFAULT_USER_SETTINGS_FILE ......... ...

  4. 页面嵌入隐藏iframe实现导出功能

    <div style="display: none"> <form action="" name="exportExcel" ...

  5. LeetCode(15): 每k个一组翻转链表

    hard! 题目描述: 给出一个链表,每 k 个节点为一组进行翻转,并返回翻转后的链表. k 是一个正整数,它的值小于或等于链表的长度.如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序. ...

  6. github git 无法读取远程仓库或无权限

    解决方法:重新设置ssh密钥 ssh-keygen -t rsa -C "http://github.com"//输入命令后按提示输入id_rsa.pub的存储地址 和密钥密码 地 ...

  7. SqlServer共用表达式(CTE)With As

    共用表表达式(CTE)可以看成是一个临时的结果集,可以再SELECT,INSERT,UPDATE,DELETE,MARGE语句中多次引用. 一好处:使用共用表表达式可以让语句更加清晰简练. 1.可以定 ...

  8. Java编程的逻辑 (27) - 剖析包装类 (中)

    ​本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...

  9. .NetCore下使用Prometheus实现系统监控和警报 (二)Linux安装

    Prometheus对Windows有相关的支持  下载地址:https://prometheus.io/download/ wget https://github.com/prometheus/pr ...

  10. CentOS 7.x 安装 Docker

    安装之前确保之前没有安装过docker为此首先删除存在的docker程序 sudo yum remove docker \ docker-common \ docker-selinux \ docke ...