当前位置: 首页 > news >正文

bzoj2395 [Balkan 2011]Timeismoney(最小乘积生成树+计算几何)

题意

每条边有两个权值\(c,t\),请求出一颗生成树,使得\(\sum c\times \sum t\)最小

题解

为什么生成树会和计算几何扯上关系……

对于每棵树,设\(x=c,y=t\),我们可以把它看成平面上的一个点,其中\(\sum c\)为横坐标,\(\sum t\)为纵坐标。那么题目就可以转化成求反比例函数图像上的点\(k=xy\)满足\(k\)最小

我们先求出一棵\(\sum c\)最小的生成树,设这个点为\(A\),和一棵\(\sum t\)最小的生成树,设为\(B\),那么如果一个点\(C\)它们更优它肯定在直线\(AB\)的下方

证明:因为\(C\)\(A,B\)更优,所以\(A,B\)肯定在这个反比例函数图像的上方。如果点\(A\)不在直线下方,画个图就会发现它必定有纵坐标小于\(B\)或者横坐标小于\(A\),与\(A,B\)的定义矛盾。故如果该点存在必定在直线\(AB\)下方

那么我们需要寻找一个在直线\(AB\)下方且离这条直线最远的一个点\(C\)来更新答案,也就是说要满足\(AB\)叉乘\(AC\)最小,即最小化

\[ \begin{aligned} Ans &=(B.x-A.x)(C.y-A.y)-(C.x-A.x)(B.y-A.y)\\ &=C.y(B.x-A.x)-C.x(B.y-A.y)-A.y(B.x-A.x)+A.x(B.y-A.y)\\ \end{aligned} \]

后面两项是常数不用考虑,那么就是要最小化\(C.y(B.x-A.x)-C.x(B.y-A.y)\)。我们把每条边的权值设为\(y(B.x-A.x)-x(B.y-A.y)\),跑一遍最小生成树就能得到\(C\)了。之后再对\((A,C),(C,B)\)递归下去即可

//minamoto
#include<bits/stdc++.h>
#define R register
#define ll long long
#define inf 1e18
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
    R int res,f=1;R char ch;
    while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
    for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
    return res*f;
}
const int N=205,M=10005;
struct eg{
    int u,v,c,t,w;
    inline bool operator <(const eg &b)const{return w<b.w;}
    inline void rd(){u=read()+1,v=read()+1,c=read(),t=read();}
}e[M];
struct node{
    int x,y;
    node(){}
    node(R int xx,R int yy):x(xx),y(yy){}
    inline node operator -(const node &b)const{return node(x-b.x,y-b.y);}
    inline ll operator *(const node &b)const{return 1ll*x*b.y-1ll*y*b.x;}
    inline bool operator >(const node &b)const{return 1ll*x*y==1ll*b.x*b.y?x>b.x:1ll*x*y>1ll*b.x*b.y;}
}mc,mt,res(inf,inf);
int n,m,u,v,fa[N];
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
node kruskal(){
    int tot=0;node P(0,0);
    fp(i,1,n)fa[i]=i;
    fp(i,1,m){
        u=find(e[i].u),v=find(e[i].v);
        if(u!=v){
            fa[u]=v,++tot;
            P.x+=e[i].c,P.y+=e[i].t;
            if(tot==n-1)break;
        }
    }
    return cmin(res,P),P;
}
void solve(node A,node B){
    fp(i,1,m)e[i].w=1ll*e[i].t*(B.x-A.x)-1ll*e[i].c*(B.y-A.y);
    sort(e+1,e+1+m);
    node C=kruskal();
    if((B-A)*(C-A)>=0)return;
    solve(A,C),solve(C,B);
}
int main(){
//  freopen("testdata.in","r",stdin);
    n=read(),m=read();
    fp(i,1,m)e[i].rd();
    fp(i,1,m)e[i].w=e[i].c;
    sort(e+1,e+1+m),mc=kruskal();
    fp(i,1,m)e[i].w=e[i].t;
    sort(e+1,e+1+m),mt=kruskal();
    solve(mc,mt);
    printf("%d %d\n",res.x,res.y);
    return 0;
}

转载于:https://www.cnblogs.com/bztMinamoto/p/10512465.html

相关文章:

  • UAV心跳机制与容器、进程数据采集
  • [Codeforces1137D]Cooperative Game
  • 数论 欧拉线性素数筛
  • lync server 2013边缘前端无法同步
  • 专业PPT制作 驼峰设计
  • P4720 【模板】扩展卢卡斯
  • Linux 遭入侵,挖矿进程被隐藏排查记录
  • 血淋淋的BUG:波音在软件开发上错在哪里?
  • Python安装常见问题(1):zipimport.ZipImportError: can't decompress data
  • 当今软件发展的现状非常适合 Cloud Native 环境
  • Leetcode PHP题解--D8 832. Flipping an Image
  • Aspx 网页跳转方法 摘要一个大佬的自用
  • 四、RabbitMQ3.7在CentOS7下的安装
  • SpringCloud SpringBoot mybatis分布式微服务云架构返回JSON格式
  • node.js学习笔记
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • Angularjs之国际化
  • CAP 一致性协议及应用解析
  • CentOS学习笔记 - 12. Nginx搭建Centos7.5远程repo
  • extract-text-webpack-plugin用法
  • git 常用命令
  • HTTP中的ETag在移动客户端的应用
  • JAVA SE 6 GC调优笔记
  • JS字符串转数字方法总结
  • PV统计优化设计
  • tweak 支持第三方库
  • Vue UI框架库开发介绍
  • yii2权限控制rbac之rule详细讲解
  • 笨办法学C 练习34:动态数组
  • 观察者模式实现非直接耦合
  • 记一次用 NodeJs 实现模拟登录的思路
  • 如何解决微信端直接跳WAP端
  • 三分钟教你同步 Visual Studio Code 设置
  • 算法之不定期更新(一)(2018-04-12)
  • 智能合约Solidity教程-事件和日志(一)
  • 《天龙八部3D》Unity技术方案揭秘
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • #我与Java虚拟机的故事#连载08:书读百遍其义自见
  • %3cli%3e连接html页面,html+canvas实现屏幕截取
  • (2)nginx 安装、启停
  • (C语言)求出1,2,5三个数不同个数组合为100的组合个数
  • (多级缓存)多级缓存
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (六)Hibernate的二级缓存
  • (原创) cocos2dx使用Curl连接网络(客户端)
  • (转载)(官方)UE4--图像编程----着色器开发
  • (轉貼) 蒼井そら挑戰筋肉擂台 (Misc)
  • *** 2003
  • ./include/caffe/util/cudnn.hpp: In function ‘const char* cudnnGetErrorString(cudnnStatus_t)’: ./incl
  • .NET 中使用 TaskCompletionSource 作为线程同步互斥或异步操作的事件
  • .NET/C# 使用 SpanT 为字符串处理提升性能
  • .netcore 6.0/7.0项目迁移至.netcore 8.0 注意事项
  • .NET应用架构设计:原则、模式与实践 目录预览
  • [ Linux ] git工具的基本使用(仓库的构建,提交)
  • [ Linux ] Linux信号概述 信号的产生