BZOJ 2395 [Balkan 2011]Time is money
题面
题解
将\(\sum_i c_i\)和\(\sum_i t_i\)分别看做分别看做\(x\)和\(y\),投射到平面直角坐标系中,于是就是找\(xy\)最小的点
于是可以先找出\(x\)最小的点\(\mathrm{A}\)和\(y\)最小的点\(\mathrm{B}\),然后找到在\(\mathrm{AB}\)左下方的最远的点\(\mathrm{C}\),如图所示:

即\(\overrightarrow{\mathrm{AB}} \times \overrightarrow{\mathrm{AC}}\)最小(因为\(\overrightarrow{\mathrm{AB}} \times \overrightarrow{\mathrm{AC}} \leq 0\))
\because \overrightarrow{\mathrm{AB}} \times \overrightarrow{\mathrm{AC}} &= (x_{\mathrm{B}} - x_{\mathrm{A}})(y_{\mathrm{C}} - y_{\mathrm{A}}) - (y_{\mathrm{B}} - y_{\mathrm{A}})(x_\mathrm{C} - x_\mathrm{A}) \\
&= (x_\mathrm B - x_\mathrm A) \times y_\mathrm C + (y_\mathrm A - y_\mathrm B) \times x_\mathrm C + y_\mathrm B x_\mathrm A - x_\mathrm B y_\mathrm A
\end{aligned}
\]
然后发现只要\((x_\mathrm B - x_\mathrm A) \times y_\mathrm C + (y_\mathrm A - y_\mathrm B) \times x_\mathrm C\)最小即可。
将每条边的权值改为\(\mathrm{g}[i][j] = (y_\mathrm A - y_\mathrm B) \times c[i][j] + (x_\mathrm B - x_\mathrm A)\times t[i][j]\),跑一遍最小生成树就可以得出答案了。
找到\(\mathrm C\)之后用叉积判断一下\(\mathrm C\)是不是在\(\mathrm{AB}\)的下方,如果是的话,就递归处理\(\mathrm{AC, CB}\)
复杂度?O(能过)
因为\(\mathrm{A, B, C}\)肯定在凸包上,又\(n\)个点的凸包期望点数为\(\sqrt{\ln n}\),
于是复杂度为\(\mathrm{O}(\sqrt{\ln n!} \times n^2)\)或者\(\mathrm{O}(\sqrt{\ln n!} \times m\log m)\)
代码
#include<cstdio>
#include<cctype>
#include<algorithm>
#define RG register
const int N(210), INF(1e9);
struct vector { int x, y; };
vector ans = (vector) {INF, INF};
inline vector operator - (const vector &lhs, const vector &rhs)
{ return (vector) {lhs.x - rhs.x, lhs.y - rhs.y}; }
inline int operator * (const vector &lhs, const vector &rhs)
{ return lhs.x * rhs.y - lhs.y * rhs.x; }
int g[N][N], f[N][N], dis[N], c[N][N], t[N][N], cdis[N], tdis[N], vis[N], n, m;
vector prim(int valx, int valy)
{
for(RG int i = 1; i <= n; i++)
for(RG int j = 1; j <= n; j++)
if(f[i][j]) g[i][j] = valx * c[i][j] + valy * t[i][j];
std::fill(dis + 1, dis + n + 1, INF);
std::fill(vis + 1, vis + n + 1, 0);
dis[1] = cdis[1] = tdis[1] = 0;
vector res = (vector) {0, 0};
for(RG int i = 1; i <= n; i++)
{
int _min = INF, x = -1;
for(RG int j = 1; j <= n; j++)
if(_min > dis[j] && (!vis[j])) _min = dis[j], x = j;
if(_min == INF) break; vis[x] = 1;
res.x += cdis[x], res.y += tdis[x];
for(RG int j = 1; j <= n; j++) if(f[x][j])
if(dis[j] > g[x][j]) dis[j] = g[x][j],
cdis[j] = c[x][j], tdis[j] = t[x][j];
}
long long sum = 1ll * res.x * res.y, _min = 1ll * ans.x * ans.y;
if(sum < _min || (sum == _min && res.x < ans.x)) ans = res;
return res;
}
void solve(const vector &A, const vector &B)
{
vector C = prim(A.y - B.y, B.x - A.x);
if((B - A) * (C - A) >= 0) return;
solve(A, C); solve(C, B);
}
int main()
{
scanf("%d%d", &n, &m);
for(RG int i = 1, x, y, _c, _t; i <= m; i++)
scanf("%d%d%d%d", &x, &y, &_c, &_t), ++x, ++y,
c[x][y] = c[y][x] = _c, t[x][y] = t[y][x] = _t,
f[x][y] = f[y][x] = 1;
vector A = prim(1, 0), B = prim(0, 1);
solve(A, B); printf("%d %d\n", ans.x, ans.y);
return 0;
}
BZOJ 2395 [Balkan 2011]Time is money的更多相关文章
- bzoj 2395 [Balkan 2011]Timeismoney——最小乘积生成树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2395 如果把 \( \sum t \) 作为 x 坐标,\( \sum c \) 作为 y ...
- BZOJ 2395 [Balkan 2011]Timeismoney(最小乘积生成树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2395 [题目大意] 给出一张无向图,每条边上有a,b两个值,求生成树, 使得suma* ...
- bzoj 2395: [Balkan 2011]Timeismoney【计算几何+最小生成树】
妙啊,是一个逼近(?)的做法 把两个值最为平面上的点坐标,然后答案也是一个点. 首先求出可能是答案的点xy分别是按照c和t排序做最小生成树的答案,然后考虑比这两个点的答案小的答案,一定在xy连线靠近原 ...
- @bzoj - 2395@ [Balkan 2011]Timeismoney
目录 @description@ @solution@ @accepted code@ @details@ @description@ 有n个城市(编号从0..n-1),m条公路(双向的),从中选择n ...
- 【BZOJ】2395: [Balkan 2011]Timeismoney
题解 最小乘积生成树! 我们把,x的总和和y的总和作为x坐标和y左边,画在坐标系上 我们选择两个初始点,一个是最靠近y轴的A,也就是x总和最小,一个是最靠近x轴的B,也就是y总和最小 连接两条直线,在 ...
- [BZOJ 2299][HAOI 2011]向量 题解(裴蜀定理)
[BZOJ 2299][HAOI 2011]向量 Description 给你一对数a,b,你可以任意使用(a,b), (a,-b), (-a,b), (-a,-b), (b,a), (b,-a), ...
- 【BZOJ2395】[Balkan 2011]Timeismoney
[BZOJ2395][Balkan 2011]Timeismoney 题面 \(darkbzoj\) 题解 如果我们只有一个条件要满足的话直接最小生成树就可以了,但是现在我们有两维啊... 我们将每个 ...
- [BZOJ 2395] Time is money
Link: BZOJ 2395 传送门 Solution: 算是一类比较经典的模型: 即对于一类经典问题,每点由1个权值化为2个权值,最终求$sigma(val_1)*sigma(val_2)$ 对于 ...
- [BZOJ 2301] [HAOI 2011] Problem b (莫比乌斯反演)(有证明)
[BZOJ 2301] [HAOI 2011] Problem b (莫比乌斯反演)(有证明) 题面 T组询问,每次给出a,b,c,d,k,求\(\sum _{i=a}^b\sum _{j=c}^d[ ...
随机推荐
- 【Kettle】2、文件夹与界面介绍
1.文件夹介绍 下载Kettle6.1解压后出现下图相关文件夹以及文件夹介绍说明: Lib:存放Kettle的核心(core)jar包.工作引擎(engine)jar包.数据库(DB) jar包.图形 ...
- sql server 查询ntext字段长度
DATALENGTH 返回任何表达式所占用的字节数. 语法 DATALENGTH ( expression ) 参数 expression 任何类型的表达式. 返回类型 int 注释 DATALENG ...
- 转:.net设计模式之单例模式
原文地址:http://terrylee.cnblogs.com/archive/2005/12/09/293509.html 概述 Singleton模式要求一个类有且仅有一个实例,并且提供了一个全 ...
- [翻译] USING GIT IN XCODE [1] 在XCODE中使用GIT[1]
USING GIT IN XCODE http://www.cimgf.com/2013/12/10/using-git-in-xcode/ Git has become a very popular ...
- pandas模块安装问题笔记
1. # pip install pandas 引用 pandas 时,没有模块 ,进行模块安装,出现一推英文提示 结果 Collecting pandas Could not fetch URL ...
- pt1000测温度
本设计使用的PT1000热电阻铂热电阻,它的阻值会随着温度的变化而改变.PT后的1000即表示它在0℃时阻值为1000欧姆,在300℃时它的阻值约为2120.515欧姆.它的工业原理:当PT1000在 ...
- U-Mail详解邮件营销优势及应用领域
最近频频有营销人员向U-Mail小编咨询:邮件营销到底有什么好处呢?与此同时,还有不少人对邮件营销存在一定的误解:邮件营销是不是只给潜在消费者发送邮件推广商品呢?其实邮件群发的应用面非常广泛,可不仅仅 ...
- IKVM.NET入门(1)
IKVM.NET是一个针对Mono和微软.net框架的java实现,其设计目的是在.NET平台上运行java程序.本文将比较详细的介绍这个工具的原理.使用入门(如何java应用转换为.NET应用.如何 ...
- 【转载】Spring最佳后台框架
https://www.quora.com/What-is-the-best-backend-arquitecture-using-spring-framework The most modern a ...
- 【洛谷】【归并排序】P1908 逆序对
[题目描述:] 猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计.最近,TOM老猫查阅到一个人类称之为“逆序对”的东西,这东西是 ...