二维最小乘积生成树学习小记

Preface

  对于形如给定一些边,其边权为xi和yi,构造一个生成树,使得

  我们称这棵树,为最小乘积生成树。我们可以考虑,沿用最小生成树的思想,把这种新颖的最小生成树做对。

Content

算法简介



  其实就是利用树形结合的思想,将点弄到平面直角坐标系上,使之明了,转化问题,求出最优解。

算法应用

  应对类似的裸题,直接裸奔

算法核心

  我们将sigma(xi)看成横坐标,sigma(yi)看成纵坐标,在坐标系中绘制出来。并在x,y轴作垂线,构成一个正方形

  我们要求一种方案xy=k最小,也就是这个正方形最小,也就是反比例函数(等面积线)y=k/x最接近坐标轴(k最小,即y最小)

  显然可以知道,把所有点列出来,构建一个下凸壳,最优的点(x,y)必定在下凸壳上。

  如下图,如果一个点不在凸包上,那么以这个点作矩阵,显然面积比以被圈圈起来的点作矩阵优,这更显然吧?

  网上大都用分治求解

  固定凸包上最接近x轴与y轴的两个节点,即求离x轴,y轴最近的点(分别以x,y为关键字作最小生成树即可,所得x,y必定最小)。

  寻找一个点C,使得C离AB最远,也就是△ABC面积最大,想要用C来更新答案。这个点C是目前最优的。

  如何找点C?我们用向量来考虑。可能觉得比较奇妙,说不出个之所以然,但是过程严谨,是没有错的,多悟一下,睡前想一想,第二天就懂了。

  向量AB=(B.x-A.x,B.y-A.y)

  向量AC=(C.x-A.x,C.y-A.y)

  根据向量定义,得出S△ABC=AB

原文地址:https://www.cnblogs.com/2016fyj/p/8393477.html

时间: 2024-10-07 19:14:29

二维最小乘积生成树学习小记的相关文章

【BZOJ2395】【Balkan 2011】Timeismoney 最小乘积生成树

链接: #include <stdio.h> int main() { puts("转载请注明出处[辗转山河弋流歌 by 空灰冰魂]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/46828379"); } 题解: 裸最小乘积生成树. 最小乘积生成树定义: 有一张n个点m条边的无向图,每条边有k个权值. 现在要取一个边集M使得其将所有点连通,并使 ∏ki=1(∑j∈Mjcost(j,vali))

HDU5697 刷题计划 dp+最小乘积生成树

分析:就是不断递归寻找靠近边界的最优解 学习博客(必须先看这个): 1:http://www.cnblogs.com/autsky-jadek/p/3959446.html 2:http://blog.csdn.net/u013849646/article/details/51524748 注:这里用的最小乘积生成树的思想,和dp结合 每次找满足条件的最优的点,只不过BZOJ裸题的满足条件是形成一棵树 这个题是大于m,生成树借用最小生成树进行求解最优,大于m用dp进行求解最优 #include

bzoj2395[Balkan 2011]Timeismoney最小乘积生成树

所谓最小乘积生成树,即对于一个无向连通图的每一条边均有两个权值xi,yi,在图中找一颗生成树,使得Σxi*Σyi取最小值. 直接处理问题较为棘手,但每条边的权值可以描述为一个二元组(xi,yi),这也就不难想到将生成树转化为平面内的点,x代表Σxi,y代表Σyi(注意这里的xi,yi指的是在生成树中的边的权值),那么问题就变成了在平面内找一个点使得x*y最小,那么显然这个点是在下凸壳上的. 因此可以首先找出两个一定在凸包上的点,例如A(minx,y),B(miny,x),在直线AB下方找一个在凸

二维练习和函数学习03/13

二维练习和函数学习03/13     二维练习     1.      抽奖活动:输入n个手机号码,滚动号码,5秒钟后停止输出中奖人号码 Console.Write("请输入人数:"); int a = int.Parse(Console.ReadLine()); string[] sj = new string[a]; for (int i = 0; i < a; i++) { Console.Write("输入第" + (i + 1) + "个人

iOS的二维码(QRCode)的学习

QRCode 二维码的学习: 需要倒入一个框架   AVFoundation 1.需要有输入设备, 2.输出设备 (解析输入设备的内容) 3.有一个会话类(输入输出完事了需要哪一个是输入那一个是输出) AVCaptureSession 4.一个展示扫描的内容 layer 二 : 然后创建 三:设置代理 --获取数据 会话类不知道哪一个是时输入设备 哪一个是 输出设备的 需要衔接她们 去绑定输入和输出设备 (做一个是否的判断). 四:设置扫描类型 五:开始扫描 [self.session star

LuoguP5540:【模板】最小乘积生成树(几何逼近)

题意:给定N点,M边,每条边有两个属性(a,b),现在让你选N-1条边出来,然后使得∑a*∑b最小.N<200,M<1e4: 思路:我们把∑a看成x,∑b看成y,那么一个方案对应一个二维坐标(x,y).假设我知道了其中两个方案[A,B],那么,如果另外一个方案C更优,则在二维平面上,C至少要满足在A和B的左边.然后[A,C],[C,B]继续下推. 这个有点像凸包的逼近,所以复杂度和凸包上的点数有关,其理论点数是sqrt(lnN)的.所以总的复杂度趋近于NlogN*sqrt(lnN): #inc

二维前缀和 - 算法学习 - 输入输出优化

2017-08-27 11:11:38 writer:pprp 二维前缀和主要用到了容斥定理,具体实现还是有点复杂的 详见代码: /* @theme:二维前缀和 @writer:pprp @declare:用到容斥定理 @date:2017/8/27 */ #include <bits/stdc++.h> using namespace std; const int maxn = 1010; int n, m, a[maxn][maxn]; //输入优化 inline int read() {

【最小乘积生成树】bzoj2395[Balkan 2011]Timeismoney

设每个点有x,y两个权值,求一棵生成树,使得sigma(x[i])*sigma(y[i])最小. 设每棵生成树为坐标系上的一个点,sigma(x[i])为横坐标,sigma(y[i])为纵坐标.则问题转化为求一个点,使得xy=k最小.即,使过这个点的反比例函数y=k/x最接近坐标轴. Step1:求得分别距x轴和y轴最近的生成树(点):A.B(分别按x权值和y权值做最小生成树即可). Step2:寻找一个在AB的靠近原点一侧的且离AB最远的生成树C,试图更新答案. [怎么找???? ——由于C离

(转)java二维数组的深度学习(静态与动态)

转自:http://developer.51cto.com/art/200906/128274.htm,谢谢 初始化: 1.动态初始化:数组定义与为数组分配空间和赋值的操作分开进行:2.静态初始化:在定义数字的同时就为数组元素分配空间并赋值:3.默认初始化:数组是引用类型,它的元素相当于类的成员变量,因此数组分配空间后,每个元素也被按照成员变量的规则被隐士初始化.实例: TestD.java(动态): 程序代码: public class TestD { public static void m