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[ ...
随机推荐
- Redis搜索引擎设计
以下图片是基于自身对知识掌握的基本能力而画出的,并没有系统全面的读过活跃于互联网大牛的著作(个人认为那样会限制自身的思维空间),因此,若图片里存在错误,敬请批评指正,谢谢! 除非互联网项目,传统的制造 ...
- mysql-5.7 持久化统计信息详解
一.持久化统计信息的意义: 统计信息用于指导mysql生成执行计划,执行计划的准确与否直接影响到SQL的执行效率:如果mysql一重启 之前的统计信息就没有了,那么当SQL语句来临时,那么mysql就 ...
- swift版的StringAttribute
swift版的StringAttribute 效果 源码 https://github.com/YouXianMing/Swift-StringAttribute // // StringAttrib ...
- 五十个小技巧提高PHP执行效率
在项目开发过程中,经常遇到了一些PHP处理程序性能底下的情况,程序运行在centos+nginx环境,虽然这个有很多的原因如:服务器本身配置,运行环境nginx服务,php-fpm配置等等,更多有一点 ...
- KInect AR沙盒制作的一点小经验
最近在微博上看到这样一条 微博 >点这看< 看起来非常有意思,就去Google了一下如何制作. 没想到这是一个开源项目,而且还告诉你如何安装 OK,接下来就说说我的制作过程. 首先,先放 ...
- 数据结构&堆&heap&priority_queue&实现
目录 什么是堆? 大根堆 小根堆 堆的操作 STL queue 什么是堆? 堆是一种数据结构,可以用来实现优先队列 大根堆 大根堆,顾名思义就是根节点最大.我们先用小根堆的建堆过程学习堆的思想. 小根 ...
- C#基础学习之委托的理解和应用
委托的使用和语法定义 委托的使用是由四步来完成的,依次为:声明委托.创建委托对象.委托关联方法.调用 我们用一个例子来说明这四步如何操作,我们完成一个老板委托员工写报告的实例,看如何实现. 首先我们应 ...
- JVM虚拟机20:内存区域详解(Eden Space、Survivor Space、Old Gen、Code Cache和Perm Gen)
1.内存区域划分 根据我们之前介绍的垃圾收集算法,限定商用虚拟机基本都采用分代收集算法进行垃圾回收.根据对象的生命周期的不同将内存划分为几块,然后根据各块的特点采用最适当的收集算法.大批对象死去.少量 ...
- SharePoint 改动passwordWeb Part部署方案
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u012025054/article/details/31773231 SharePoint 改动pa ...
- BZOJ3160:万径人踪灭(FFT,Manacher)
Solution $ans=$回文子序列$-$回文子串的数目. 后者可以用$manacher$直接求. 前者设$f[i]$表示以$i$为中心的对称的字母对数. 那么回文子序列的数量也就是$\sum_{ ...