题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2395

如果把 \( \sum t \) 作为 x 坐标,\( \sum c \) 作为 y 坐标,则每棵生成树都是二维平面上的一个点。

答案是二维平面上的一个下凸壳。先求出只考虑 t 的最小生成树和只考虑 c 的最小生成树,它们就是凸壳的两端。

已知两端,考虑递归下去,则要找到距离这两端构成的直线最远的点。

这就是点到直线的距离,等价于三个点组成的三角形面积最小;考虑叉积公式,得出面积关于要找的点的 x , y 坐标的式子,形如 A*x + B*y ;

给边权乘上系数,就能求最小生成树得到该点;如果面积是负的,就求最小生成树,否则求最大生成树。

判断是否不用再往下递归,本来写的是找到的那个点就是两端点之一,结果T了;写成找到的那个点在两端点的连线上就可以了。

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N=,M=1e4+;
int n,m,fa[N],dep[N];
struct Ed{int t,c,w,x,y;}ed[M];
struct Node{
int t,c;ll w;
Node(){t=c=w=;}
bool operator== (const Node &b)const
{return t==b.t&&c==b.c;}
}ans;
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return fx?ret:-ret;
}
void frh(Node p){if(p.w<ans.w||(p.w==ans.w&&p.c<ans.c))ans=p;}
bool cmp(Ed u,Ed v){return u.w<v.w;}
int fnd(int a){return fa[a]==a?a:fa[a]=fnd(fa[a]);}
ll Cross(int x1,int y1,int x2,int y2)
{return (ll)x1*y2-(ll)x2*y1;}
Node calc(int t0,int t1)
{
for(int i=;i<=m;i++)ed[i].w=(ll)t0*ed[i].t+(ll)t1*ed[i].c;
sort(ed+,ed+m+,cmp);
memset(dep,,sizeof dep);
for(int i=;i<=n;i++)fa[i]=i;
Node ret;
for(int i=,u,v,cnt=;i<=m;i++)
{
if((u=fnd(ed[i].x))==(v=fnd(ed[i].y)))continue;
if(dep[u]>dep[v])swap(u,v);
fa[u]=v;if(dep[u]==dep[v])dep[v]++;
ret.t+=ed[i].t;ret.c+=ed[i].c;
cnt++;if(cnt==n-)break;
}
ret.w=(ll)ret.t*ret.c;
return ret;
}
void solve(Node p0,Node p1)
{
int st=p1.c-p0.c,sc=p0.t-p1.t;
Node res=calc(st,sc);frh(res);
// if(res==p0||res==p1)return;
if(Cross(p1.t-res.t,p1.c-res.c,p0.t-res.t,p0.c-res.c)>=)return;
solve(p0,res); solve(res,p1);
}
int main()
{
n=rdn();m=rdn();
for(int i=;i<=m;i++)
ed[i].x=rdn()+,ed[i].y=rdn()+,ed[i].t=rdn(),ed[i].c=rdn();
ans.t=ans.c=1e9;ans.w=1e18;
Node p0=calc(,),p1=calc(,);
frh(p0);frh(p1);
solve(p0,p1);
printf("%d %d\n",ans.t,ans.c);
return ;
}

bzoj 2395 [Balkan 2011]Timeismoney——最小乘积生成树的更多相关文章

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

    所谓最小乘积生成树,即对于一个无向连通图的每一条边均有两个权值xi,yi,在图中找一颗生成树,使得Σxi*Σyi取最小值. 直接处理问题较为棘手,但每条边的权值可以描述为一个二元组(xi,yi),这也 ...

  2. Bzoj2395: [Balkan 2011]Timeismoney(最小乘积生成树)

    问题描述 每条边两个权值 \(x,y\),求一棵 \((\sum x) \times (\sum y)\) 最小的生成树 Sol 把每一棵生成树的权值 \(\sum x\) 和 \(\sum y\) ...

  3. @bzoj - 2395@ [Balkan 2011]Timeismoney

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 有n个城市(编号从0..n-1),m条公路(双向的),从中选择n ...

  4. BZOJ 2395 [Balkan 2011]Timeismoney(最小乘积生成树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2395 [题目大意] 给出一张无向图,每条边上有a,b两个值,求生成树, 使得suma* ...

  5. bzoj 2395: [Balkan 2011]Timeismoney【计算几何+最小生成树】

    妙啊,是一个逼近(?)的做法 把两个值最为平面上的点坐标,然后答案也是一个点. 首先求出可能是答案的点xy分别是按照c和t排序做最小生成树的答案,然后考虑比这两个点的答案小的答案,一定在xy连线靠近原 ...

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

    链接: #include <stdio.h> int main() { puts("转载请注明出处[辗转山河弋流歌 by 空灰冰魂]谢谢"); puts("网 ...

  7. 【BZOJ】2395: [Balkan 2011]Timeismoney

    题解 最小乘积生成树! 我们把,x的总和和y的总和作为x坐标和y左边,画在坐标系上 我们选择两个初始点,一个是最靠近y轴的A,也就是x总和最小,一个是最靠近x轴的B,也就是y总和最小 连接两条直线,在 ...

  8. bzoj 2395 Timeismoney —— 最小乘积生成树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2395 参考博客:https://www.cnblogs.com/autsky-jadek/p ...

  9. P5540-[BalkanOI2011]timeismoney|最小乘积生成树【最小生成树,凸壳】

    正题 题目链接:https://www.luogu.com.cn/problem/P5540 题目大意 给出\(n\)个点\(m\)条边边权是一个二元组\((a_i,b_i)\),求出一棵生成树最小化 ...

随机推荐

  1. 安装Linux环境

    虚拟机:虚拟机(Virtual Machine),在计算机科学中的体系结构里,是指一种特殊的软件,他可以在计算机平台和终端用户之间建立一种环境,而终端用户则是基于这个软件所建立的环境来操作软件.在计算 ...

  2. 通过windows的超级终端连接华为交换机

    如果你的电脑没有带COM接口 可以找一个COM--->USB的转换器 我前面有介绍过这么安装COM转USB设备的驱动 2 先打开你电脑的设备管理器 看看你的com接口数字编号 这里看到的是COM ...

  3. laravel中上传图片之后图片的处理

    $file=Input::file('file'); if ($file->isValid()){ $entension=$file->getClientOriginalExtension ...

  4. 一月收集几个有用的谷歌Chrome插件

    谷歌Chrome自推出以来已经从一个简单的浏览器演变成一个复杂的浏览器,这得益于根据浏览器写出的非常有用和强大的扩展.作为一名开发人员,我们关注的是网页设计和开发部分的那些插件对我们有帮助,几个比较熟 ...

  5. Maven入门-2.Maven一些核心概念介绍

    1.Maven仓库2.Maven坐标3.Maven插件和目标4.Maven生命周期4.1 clean:清理项目4.2 default:构建项目(重要)4.3 site:建立项目站点 1.Maven仓库 ...

  6. 《Effective C++》第2章 构造/析构/赋值运算(1)-读书笔记

    章节回顾: <Effective C++>第1章 让自己习惯C++-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(1)-读书笔记 <Effecti ...

  7. python3精简笔记(二)——函数

    函数 下面的地址可以查看函数: https://docs.python.org/3/library/functions.html 也可以在交互式命令行通过help()查看函数的帮助信息. 如: > ...

  8. 课堂/会议同屏教学解决方案之RTSP/RTP over UDP组播解决方案

    问题 在之前的博客<EasyIPCamera实现Windows PC桌面.安卓Android桌面同屏直播,助力无纸化会议系统>我们描述了一套基于EasyIPCamera的同屏功能,但是这个 ...

  9. SQL基础五(作业代码)

    create database stuinfo create table student ( mid ) not null primary key, mname ) not null ) create ...

  10. 在FP与DDD的道路上越走越远

    托辞 最近一口气读了若干本FP方面的书,可人是越来越懒了,要整理个什么东西却也没有那个精力,所以简单扔几张图,算是给自己一个提醒吧. 在此期间,我用并不纯熟的Scala和Groovy练了一把手.虽然只 ...