题面

题解

将\(\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\))

\[\begin{aligned}
\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的更多相关文章

  1. bzoj 2395 [Balkan 2011]Timeismoney——最小乘积生成树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2395 如果把 \( \sum t \) 作为 x 坐标,\( \sum c \) 作为 y ...

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

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

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

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

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

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

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

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

  6. [BZOJ 2299][HAOI 2011]向量 题解(裴蜀定理)

    [BZOJ 2299][HAOI 2011]向量 Description 给你一对数a,b,你可以任意使用(a,b), (a,-b), (-a,b), (-a,-b), (b,a), (b,-a), ...

  7. 【BZOJ2395】[Balkan 2011]Timeismoney

    [BZOJ2395][Balkan 2011]Timeismoney 题面 \(darkbzoj\) 题解 如果我们只有一个条件要满足的话直接最小生成树就可以了,但是现在我们有两维啊... 我们将每个 ...

  8. [BZOJ 2395] Time is money

    Link: BZOJ 2395 传送门 Solution: 算是一类比较经典的模型: 即对于一类经典问题,每点由1个权值化为2个权值,最终求$sigma(val_1)*sigma(val_2)$ 对于 ...

  9. [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[ ...

随机推荐

  1. Redis搜索引擎设计

    以下图片是基于自身对知识掌握的基本能力而画出的,并没有系统全面的读过活跃于互联网大牛的著作(个人认为那样会限制自身的思维空间),因此,若图片里存在错误,敬请批评指正,谢谢! 除非互联网项目,传统的制造 ...

  2. mysql-5.7 持久化统计信息详解

    一.持久化统计信息的意义: 统计信息用于指导mysql生成执行计划,执行计划的准确与否直接影响到SQL的执行效率:如果mysql一重启 之前的统计信息就没有了,那么当SQL语句来临时,那么mysql就 ...

  3. swift版的StringAttribute

    swift版的StringAttribute 效果 源码 https://github.com/YouXianMing/Swift-StringAttribute // // StringAttrib ...

  4. 五十个小技巧提高PHP执行效率

    在项目开发过程中,经常遇到了一些PHP处理程序性能底下的情况,程序运行在centos+nginx环境,虽然这个有很多的原因如:服务器本身配置,运行环境nginx服务,php-fpm配置等等,更多有一点 ...

  5. KInect AR沙盒制作的一点小经验

    最近在微博上看到这样一条 微博  >点这看< 看起来非常有意思,就去Google了一下如何制作. 没想到这是一个开源项目,而且还告诉你如何安装 OK,接下来就说说我的制作过程. 首先,先放 ...

  6. 数据结构&堆&heap&priority_queue&实现

    目录 什么是堆? 大根堆 小根堆 堆的操作 STL queue 什么是堆? 堆是一种数据结构,可以用来实现优先队列 大根堆 大根堆,顾名思义就是根节点最大.我们先用小根堆的建堆过程学习堆的思想. 小根 ...

  7. C#基础学习之委托的理解和应用

    委托的使用和语法定义 委托的使用是由四步来完成的,依次为:声明委托.创建委托对象.委托关联方法.调用 我们用一个例子来说明这四步如何操作,我们完成一个老板委托员工写报告的实例,看如何实现. 首先我们应 ...

  8. JVM虚拟机20:内存区域详解(Eden Space、Survivor Space、Old Gen、Code Cache和Perm Gen)

    1.内存区域划分 根据我们之前介绍的垃圾收集算法,限定商用虚拟机基本都采用分代收集算法进行垃圾回收.根据对象的生命周期的不同将内存划分为几块,然后根据各块的特点采用最适当的收集算法.大批对象死去.少量 ...

  9. SharePoint 改动passwordWeb Part部署方案

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u012025054/article/details/31773231 SharePoint 改动pa ...

  10. BZOJ3160:万径人踪灭(FFT,Manacher)

    Solution $ans=$回文子序列$-$回文子串的数目. 后者可以用$manacher$直接求. 前者设$f[i]$表示以$i$为中心的对称的字母对数. 那么回文子序列的数量也就是$\sum_{ ...