以下内容均为转载

http://www.cnblogs.com/ftae/p/6947497.html

poj2728(最小比率生成树)

 

poj2728

题意

给出 n 个点的坐标和它的高度,求一颗生成树使得树上所连边的两点高度差之和除以距离之和最小。

分析

01分数规划+最小生成树。
对于所有的边,在求最小生成树过程中有选或不选的问题,
首先根据01分数规划,我们要使 l=∑i=1nheight[i]∗exist[i]∑i=1ndis[i]∗exist[i]

(exist[i]表示是否有这条边)最小,
F(l)=∑height[i]∗exist[i]−l∗∑dis[i]∗exist[i]

,我们要使 l

尽可能的小, F(l)

l

减小而递增,如果 F(l)<0


∑i=1nheight[i]∗exist[i]∑i=1ndis[i]∗exist[i]<l

,即存在更优的 l

,当 F(l)=0

时,即为最终最终答案 l


D(l)=height[i]−dis[i]∗l

,把它作为边,求最小生成树,那么求得值 F(l)

一定是尽可能小的,越有可能出现更优的 l

本题适于采用迭代法,因为在求最小生成树的过程中,就可以计算出更优的 l

值。

code(二分法)

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int MAXN = 1e3 + 10;
const double INF = 1e15;
int n;
double dist(double x1, double y1, double x2, double y2) {
return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
struct node {
double x, y, h;
}a[MAXN];
double height[MAXN][MAXN];
double map[MAXN][MAXN];
double dis[MAXN];
int vis[MAXN];
double prime(double rate) {
double sum = 0;
memset(vis, 0, sizeof vis);
for(int i = 1; i <= n; i++) {
dis[i] = INF;
}
dis[1] = 0;
for(int i = 0; i < n; i++) {
double MIN = INF;
int k;
for(int j = 1; j <= n; j++) {
if(!vis[j] && dis[j] < MIN) MIN = dis[k = j];
}
vis[k] = 1;
sum += MIN;
for(int j = 1; j <= n; j++) {
if(!vis[j] && dis[j] > height[k][j] - rate * map[k][j]) {
dis[j] = height[k][j] - rate * map[k][j];
}
}
}
return sum;
}
void solve() {
double l = 0, r = 1e5, mid = 0;
while(r - l > 1e-6) {
mid = (l + r) / 2;
if(prime(mid) < 0) r = mid;
else l = mid;
}
printf("%.3f\n", mid);
}
int main() {
while(cin >> n && n) {
for(int i = 1; i <= n; i++) {
cin >> a[i].x >> a[i].y >> a[i].h;
for(int j = 1; j <= i; j++) {
map[i][j] = map[j][i] = dist(a[i].x, a[i].y, a[j].x, a[j].y);
height[i][j] = height[j][i] = abs(a[i].h - a[j].h);
}
}
solve();
}
return 0;
}

code(迭代法)

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int MAXN = 1e3 + 10;
const double INF = 1e15;
int n;
double dist(double x1, double y1, double x2, double y2) {
return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
struct node {
double x, y, h;
}a[MAXN];
double height[MAXN][MAXN];
double map[MAXN][MAXN];
double dis[MAXN];
int vis[MAXN], pre[MAXN];
double prime(double rate) {
double sum = 0;
double sumh = 0, sumd = 0;
memset(vis, 0, sizeof vis);
for(int i = 1; i <= n; i++) {
dis[i] = INF;
pre[i] = 0;
}
dis[1] = 0;
for(int i = 0; i < n; i++) {
double MIN = INF;
int k;
for(int j = 1; j <= n; j++) {
if(!vis[j] && dis[j] < MIN) {
MIN = dis[k = j];
}
}
vis[k] = 1;
sum += MIN;
sumd += map[pre[k]][k];
sumh += height[pre[k]][k];
for(int j = 1; j <= n; j++) {
if(!vis[j] && dis[j] > height[k][j] - rate * map[k][j]) {
dis[j] = height[k][j] - rate * map[k][j];
pre[j] = k;
}
}
}
return sumh / sumd;
}
void solve() {
double k = 0, tmp;
while(1) {
tmp = prime(k);
if(fabs(tmp - k) < 1e-6) break;
else k = tmp;
}
printf("%.3f\n", k);
} int main() {
while(cin >> n && n) {
for(int i = 1; i <= n; i++) {
cin >> a[i].x >> a[i].y >> a[i].h;
for(int j = 1; j <= i; j++) {
map[i][j] = map[j][i] = dist(a[i].x, a[i].y, a[j].x, a[j].y);
height[i][j] = height[j][i] = abs(a[i].h - a[j].h);
}
}
solve();
}
return 0;
}

最小比率树 poj2728的更多相关文章

  1. [LeetCode] Minimum Height Trees 最小高度树

    For a undirected graph with tree characteristics, we can choose any node as the root. The result gra ...

  2. [BZOJ3754]Tree之最小方差树

    3754: Tree之最小方差树 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 402  Solved: 152[Submit][Status][Di ...

  3. 【BZOJ-4435】Juice Junctions 最小割树(分治+最小割)+Hash

    4435: [Cerc2015]Juice Junctions Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 20  Solved: 11[Submi ...

  4. 【BZOJ-2229】最小割 最小割树(最大流+分治)

    2229: [Zjoi2011]最小割 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1565  Solved: 560[Submit][Status ...

  5. [swustoj 404] 最小代价树

    最小代价树(0404) 问题描述 以下方法称为最小代价的字母树:给定一正整数序列,例如:4,1,2,3,在不改变数的位置的条件下把它们相加,并且用括号来标记每一次加法所得到的和. 例如:((4+1)+ ...

  6. 【UVA 10816】 Travel in Desert (最小瓶颈树+最短路)

    [题意] 有n个绿洲, m条道路,每条路上有一个温度,和一个路程长度,从绿洲s到绿洲t,求一条道路的最高温度尽量小, 如果有多条, 选一条总路程最短的. InputInput consists of ...

  7. [洛谷]P3729 曼哈顿计划EX(最小割树/等价流树)

    题目大意:给出一张n个点m条边的无向图,每个点有点权,q次询问,每次给出k,要求选出若干个点点权之和不小于k,求一个最大的值x,使得选出的点中任意两点之间至少有x条互不相交的链.(n<=550, ...

  8. [Swift]LeetCode310. 最小高度树 | Minimum Height Trees

    For an undirected graph with tree characteristics, we can choose any node as the root. The result gr ...

  9. BZOJ4519[Cqoi2016]不同的最小割——最小割树+map

    题目描述 学过图论的同学都知道最小割的概念:对于一个图,某个对图中结点的划分将图中所有结点分成 两个部分,如果结点s,t不在同一个部分中,则称这个划分是关于s,t的割.对于带权图来说,将 所有顶点处在 ...

随机推荐

  1. Spring Boot JPA 中transaction的使用

    文章目录 @Transactional的实现 @Transactional的使用 Transaction的传播级别 REQUIRED SUPPORTS MANDATORY NEVER NOT_SUPP ...

  2. Scala教程之:函数式的Scala

    文章目录 高阶函数 强制转换方法为函数 方法嵌套 多参数列表 样例类 比较 拷贝 模式匹配 密封类 单例对象 伴生对象 正则表达式模式 For表达式 Scala是一门函数式语言,接下来我们会讲一下几个 ...

  3. 【高并发】又一个朋友面试栽在了Thread类的stop()方法和interrupt()方法上!

    写在前面 新一轮的面试已经过去,可能是疫情的原因吧,很多童鞋纷纷留言说今年的面试题难度又提高了,尤其是对并发编程的知识.我细想了下,也许有那么点疫情的原因吧,但无论面试的套路怎么变,只要掌握了核心知识 ...

  4. 【三剑客】awk函数

    1. 内置函数 awk的内置函数有算术.字符串.时间.位操作和其它杂项的函数. 1.1 算术函数 atan2(y,x)  返回弧度的反正切(y/x) cos(expr)  返回expr的余弦(以弧度形 ...

  5. Tomcat 8 Host-Manager配置访问的方法,全网唯一正确配置

    2019独角兽企业重金招聘Python工程师标准>>> 环境: 操作系统:         Linux version 2.6.32-696.10.1.el6.x86_64 (moc ...

  6. 演示:配置日志发送到syslog日志服务器

    演示目标:配置网络环境中的交换机和路由器将日志发送到syslog日志服务器. 演示环境:如下图10.54所示的演示环境. 演示背景:要求部署网络中的syslog服务器,集中的收集交换机S1和路由器R1 ...

  7. Function-time()

    time()函数返回自1970年1月1日0点以来经过的秒数,每秒变化一次? time()函数定义在头文件<time.h>中,原型是: time_t time(time_t *arg); 如 ...

  8. RF(IF 判断)

    1.关键字 Run Keyword If,格式如下: ELSE   必须大写 ELSE   前面需要加 "..." 表示缩进 Run Keyword If a == b log T ...

  9. DeepWalk论文精读:(4)总结及不足

    模块4 1 研究背景 随着互联网的发展,社交网络逐渐复杂化.多元化.在一个社交网络中,充斥着不同类型的用户,用户间产生各式各样的互动联系,形成大小不一的社群.为了对社交网络进行研究分析,需要将网络中的 ...

  10. Ansible入门知识

    一.ansible概述 Ansible是一款为类Unix系统开发的自由开源的配置和自动化工具.它用Python写成,类似于saltstack和Puppet,但是有一个不同和优点是我们不需要在节点中安装 ...