当前位置:网站首页>洛谷P5540 [BalkanOI2011] timeismoney | 最小乘积生成树 题解
洛谷P5540 [BalkanOI2011] timeismoney | 最小乘积生成树 题解
2022-04-23 12:26:00 【q779】
洛谷P5540 [BalkanOI2011] timeismoney | 最小乘积生成树 题解
题目链接:P5540 [BalkanOI2011] timeismoney | 最小乘积生成树
题意:给出一个 n n n 个点 m m m 条边的无向图,第 i i i 条边有两个权值 a i a_i ai 和 b i b_i bi 。
求该图的一棵生成树 T T T ,使得
( ∑ e ∈ T a e ) × ( ∑ e ∈ T b e ) \left(\sum_{e\in T}a_e\right)\times\left(\sum_{e\in T}b_e\right) (e∈T∑ae)×(e∈T∑be)最小
注意到对于一棵生成树,式子中的左右两边均为常数
考虑将生成树映射到平面上的点 ( x , y ) (x,y) (x,y)
其中 x = ∑ e ∈ T a e , y = ∑ e ∈ T b e x=\sum\limits_{e\in T}a_e,y=\sum\limits_{e\in T}b_e x=e∈T∑ae,y=e∈T∑be
那么问题就转化为了求一个点 ( x , y ) (x,y) (x,y) 使得 x × y x\times y x×y 最小
可以发现这些点的分布存在边界
即 x x x 特别大 y y y 特别小的时候以及 y y y 特别大 x x x 特别小的时候
这两种情况分别对应点 A A A 和 B B B
则有 A A A 为距离 x x x 轴最近的点, B B B 为距离 y y y 轴最近的点
对于直线 A B AB AB ,显然在 A B AB AB 上方的不是优解
根据反比例函数的性质,可以发现这个解一定在以 A , B A,B A,B 为端点的下凸包上
由于我们不可能枚举出所有的生成树然后求二维凸包
考虑递归求解,不知道大家知不知道割圆术,不知道也没关系
这个解法有点像割圆术
首先找出距离直线 A B AB AB 最远的点 C C C (在 A B AB AB 下方)
然后递归 A C AC AC 和 C B CB CB ,即可求出解
如何寻找 C C C 点呢?可以发现此时 S △ A B C S_{\triangle ABC} S△ABC 取到了最大值
而 S △ A B C = − 1 2 A B * × A C * S_{\triangle ABC} = -\dfrac{1}{2}\overset{\longrightarrow}{AB}\times \overset{\longrightarrow}{AC} S△ABC=−21AB*×AC*
(注:这里写的不是很规范,其实应该除以一个单位向量 z \boldsymbol{z} z 的,不重要不管了)
推柿子环节 qwq
A B * × A C * = ( x B − x A ) ( y C − y A ) − ( y B − y A ) ( x C − x A ) = ( x B − x A ) × y C + ( y A − y B ) × x C + y B x A − x B y A \begin{aligned} \overset{\longrightarrow}{AB}\times \overset{\longrightarrow}{AC} &= (x_B-x_A)(y_C-y_A)-(y_B-y_A)(x_C-x_A)\\ &=(x_B-x_A)\times y_C + (y_A-y_B)\times x_C + y_Bx_A-x_By_A \end{aligned} AB*×AC*=(xB−xA)(yC−yA)−(yB−yA)(xC−xA)=(xB−xA)×yC+(yA−yB)×xC+yBxA−xByA
可以发现后面两项是定值
因此我们将边权设为 ( x B − x A ) b i + ( y A − y B ) a i (x_B-x_A)b_i+(y_A-y_B)a_i (xB−xA)bi+(yA−yB)ai ,然后跑最小生成树即可
由于 n n n 很小,且凸包上的期望点数分析极其复杂
本题复杂度可以近似看作 O ( k m log m ) O(km\log m) O(kmlogm),其中 k k k 为一个小常数,据说是 ln n \sqrt{\ln n} lnn ,不太清楚
代码如下
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define INF 0x3f3f3f3f3f3f3f3f
#define gc() readchar()
#define pc(a) putchar(a)
#define SIZ (int)(1e5+15)
char buf1[SIZ],*p1,*p2;
char readchar()
{
if(p1==p2)p1=buf1,p2=buf1+fread(buf1,1,SIZ,stdin);
return p1==p2?EOF:*p1++;
}
template<typename T>void read(T &k)
{
char ch=gc();T x=0,f=1;
while(!isdigit(ch)){
if(ch=='-')f=-1;ch=gc();}
while(isdigit(ch)){
x=(x<<1)+(x<<3)+(ch^48);ch=gc();}
k=x*f;
}
template<typename T>void write(T k)
{
if(k<0){
k=-k;pc('-');}
static T stk[66];T top=0;
do{
stk[top++]=k%10,k/=10;}while(k);
while(top){
pc(stk[--top]+'0');}
}
#define N (int)(2e2+15)
#define M (int)(1e4+15)
int n,m;
struct Edge
{
int u,v,a,b,w,next;
}e[M];
struct vct
{
int x,y;
}ans;
int f[N];
vct operator-(vct a,vct b){
return (vct){
a.x-b.x,a.y-b.y};}
int cross(vct a,vct b){
return a.x*b.y-a.y*b.x;}
void init(){
for(int i=1; i<=n; i++) f[i]=i;}
int find(int x){
return f[x]==x?x:f[x]=find(f[x]);}
void merge(int u,int v){
u=find(u);v=find(v);f[u]=v;}
vct kruskal()
{
sort(e+1,e+1+m,[](Edge a,Edge b){
return a.w<b.w;
});
init();
vct res={
0,0};
int cnt=0;
for(int i=1; i<=m; i++)
{
int u=find(e[i].u),v=find(e[i].v);
if(u!=v)
{
merge(u,v);
res.x+=e[i].a;
res.y+=e[i].b;
if(++cnt==n-1)break;
}
}
int Ans=ans.x*ans.y,Res=res.x*res.y;
if(Ans>Res||Ans==Res&&ans.x>res.x)ans=res;
return res;
}
void solve(vct A,vct B)
{
for(int i=1; i<=m; i++)
e[i].w=e[i].b*(B.x-A.x)+e[i].a*(A.y-B.y);
vct C=kruskal();
if(cross(B-A,C-A)>=0)return;
solve(A,C);solve(C,B);
}
signed main()
{
read(n);read(m);
ans={
0x3f3f3f3f,0x3f3f3f3f};
for(int i=1; i<=m; i++)
{
read(e[i].u);read(e[i].v);
read(e[i].a);read(e[i].b);
e[i].u++;e[i].v++;
}
for(int i=1; i<=m; i++)
e[i].w=e[i].a;
vct A=kruskal();
for(int i=1; i<=m; i++)
e[i].w=e[i].b;
vct B=kruskal();
solve(A,B);
printf("%lld %lld\n",ans.x,ans.y);
return 0;
}
转载请说明出处
版权声明
本文为[q779]所创,转载请带上原文链接,感谢
https://blog.csdn.net/qq_50332374/article/details/124348614
边栏推荐
- 第二十六课 类的静态成员函数
- QT redraw events and cuts
- Database Navigator 使用默认MySQL连接提示:The server time zone value ‘Öйú±ê׼ʱ¼ä’ is unrecognized or repres
- Lesson 25 static member variables of classes
- STM32控制步进电机(ULN2003+28byj)
- 智能多线弹性云增加独立的IP地址,如何实现多线功能?
- SQL exercise (I)
- 程序员如何用130行代码敲定核酸统计
- Sigmoid function of activation function
- XinChaCha Trust SSL Organization Validated
猜你喜欢

Dialogue with Bruce, author of PostgreSQL: "changing careers" is to better move forward

Qt绘制图像

Message queuing overview

Fastjson 2 is coming, the performance continues to improve, and it can fight for another ten years

【Redis 系列】redis 学习十三,Redis 常问简单面试题

Idea code quality specification plug-in sonarlint

Database Navigator 使用默认MySQL连接提示:The server time zone value ‘Öйú±ê׼ʱ¼ä’ is unrecognized or repres

Tips for installing MySQL service in windows11: Install / Remove of the Service denied

After a circle, I sorted out this set of interview questions..

力扣刷题之完全二叉树的节点个数
随机推荐
软件测试对于减少程序BUG有多大帮助?
传统企业如何应对数字化转型?这些书给你答案
A graphic designer's fantasy world | ones characters
Zigbee之CC2530最小系统及寄存器配置(1)
电脑系统卡如何解决?
面了一圈,整理了这套面试题。。
5分钟NLP:Text-To-Text Transfer Transformer (T5)统一的文本到文本任务模型
QT draw image
Source code analysis of synchronousqueue
QT double buffer drawing
程序员如何用130行代码敲定核酸统计
On lambda powertools typescript
In idea Solution to the problem of garbled code in Chinese display of properties file
Flash project cross domain interception and DBM database learning [Baotou cultural and creative website development]
运行报错:找不到或无法加载主类 com.xxx.Application
Number of nodes of complete binary tree
力扣刷题之完全二叉树的节点个数
Fastjson 2 来了,性能继续提升,还能再战十年
[unity note] basic lighting in l4unity
Database Navigator 使用默认MySQL连接提示:The server time zone value ‘Öйú±ê׼ʱ¼ä’ is unrecognized or repres