bzoj 2395 Timeismoney —— 最小乘积生成树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2395
参考博客:https://www.cnblogs.com/autsky-jadek/p/3959446.html
但复杂度不太会算;
递归边界不要取两个点相等,而是叉积>=0 。
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int const xn=,xm=1e4+;
int n,m,fa[xn],dis[xn];
ll ansx,ansy;
struct N{
int u,v,a,b; ll w;
bool operator < (const N &y) const
{return w<y.w;}
}ed[xm];
struct P{
ll x,y;
P(ll x=,ll y=):x(x),y(y) {}
};
P operator - (const P &A,const P &B){return P(A.x-B.x,A.y-B.y);}
ll cross(P A,P B){return A.x*B.y-A.y*B.x;}
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return f?ret:-ret;
}
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
void uni(int x,int y)
{
if(dis[x]==dis[y])fa[x]=y,dis[y]++;
else if(dis[x]<dis[y])fa[x]=y;
else fa[y]=x;
}
P kruskal()
{
int cnt=; P ret=P(,);
memset(dis,,sizeof dis);
for(int i=;i<=n;i++)fa[i]=i;
sort(ed+,ed+m+);
for(int i=;i<=m;i++)
{
int x=find(ed[i].u),y=find(ed[i].v);
if(x==y)continue;
ret.x+=ed[i].a; ret.y+=ed[i].b;
uni(x,y); cnt++;
if(cnt==n-)break;
}
return ret;
}
bool eql(P A,P B){return A.x==B.x&&A.y==B.y;}
void solve(P A,P B)
{
for(int i=;i<=m;i++)ed[i].w=ed[i].b*(B.x-A.x)+ed[i].a*(A.y-B.y);
P C=kruskal();
if(cross(B-A,C-A)>=)return;//>=0
//if(eql(A,C)||eql(B,C))return;
if((C.x*C.y<ansx*ansy)||(C.x*C.y==ansx*ansy&&C.x<ansx))ansx=C.x,ansy=C.y;
solve(A,C); solve(C,B);
}
int main()
{
n=rd(); m=rd();
for(int i=;i<=m;i++)
ed[i].u=rd()+,ed[i].v=rd()+,ed[i].a=rd(),ed[i].b=rd();
for(int i=;i<=m;i++)ed[i].w=ed[i].a;
P A=kruskal();
for(int i=;i<=m;i++)ed[i].w=ed[i].b;
P B=kruskal();
if((A.x*A.y<B.x*B.y)||(A.x*A.y==B.x*B.y&&A.x<B.x))ansx=A.x,ansy=A.y;
else ansx=B.x,ansy=B.y;
solve(A,B);
printf("%lld %lld\n",ansx,ansy);
return ;
}
bzoj 2395 Timeismoney —— 最小乘积生成树的更多相关文章
- bzoj2395[Balkan 2011]Timeismoney最小乘积生成树
所谓最小乘积生成树,即对于一个无向连通图的每一条边均有两个权值xi,yi,在图中找一颗生成树,使得Σxi*Σyi取最小值. 直接处理问题较为棘手,但每条边的权值可以描述为一个二元组(xi,yi),这也 ...
- 【BZOJ2395】【Balkan 2011】Timeismoney 最小乘积生成树
链接: #include <stdio.h> int main() { puts("转载请注明出处[辗转山河弋流歌 by 空灰冰魂]谢谢"); puts("网 ...
- Bzoj2395: [Balkan 2011]Timeismoney(最小乘积生成树)
问题描述 每条边两个权值 \(x,y\),求一棵 \((\sum x) \times (\sum y)\) 最小的生成树 Sol 把每一棵生成树的权值 \(\sum x\) 和 \(\sum y\) ...
- bzoj 2395 [Balkan 2011]Timeismoney——最小乘积生成树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2395 如果把 \( \sum t \) 作为 x 坐标,\( \sum c \) 作为 y ...
- P5540-[BalkanOI2011]timeismoney|最小乘积生成树【最小生成树,凸壳】
正题 题目链接:https://www.luogu.com.cn/problem/P5540 题目大意 给出\(n\)个点\(m\)条边边权是一个二元组\((a_i,b_i)\),求出一棵生成树最小化 ...
- 洛谷 P5540 - [BalkanOI2011] timeismoney | 最小乘积生成树(最小生成树)
洛谷题面传送门 大概是一个比较 trivial 的小 trick?学过了就不要忘了哦( 莫名奇妙地想到了 yyq 的"hot tea 不常有,做过了就不能再错过了" 首先看到这种二 ...
- HDU5697 刷题计划 dp+最小乘积生成树
分析:就是不断递归寻找靠近边界的最优解 学习博客(必须先看这个): 1:http://www.cnblogs.com/autsky-jadek/p/3959446.html 2:http://blog ...
- 【算法】最小乘积生成树 & 最小乘积匹配 (HNOI2014画框)
今天考试的时候果然题目太难于是我就放弃了……转而学习了一下最小乘积生成树. 最小乘积生成树定义: (摘自网上一篇博文). 我们主要解决的问题就是当k = 2时,如何获得最小的权值乘积.我们注意到一张图 ...
- Luogu5540 最小乘积生成树
Luogu5540 最小乘积生成树 题目链接:洛谷 题目描述:对于一个\(n\)个点\(m\)条边的无向连通图,每条边有两个边权\(a_i,b_i\),求使\((\sum a_i)\times (\s ...
随机推荐
- 宇视摄像机/NVR OCX插件插件安装出现:Failed to register ocx, error code 14001 错误的解决方法
最近在使用EasyNVR接入海康.宇视的摄像机进行景观直播的项目时,需要进入宇视设备进行音视频编码参数的调整,要说呢,海康的产品好就是要好很多: 海康的设备后台管理页面,不需要装插件也能进去,而且能调 ...
- On the importance of initialization and momentum in deep learning
Ilya Sutskever1 ilyasu@google.com James Martens jmartens@cs.toronto.edu George Dahl gdahl@cs.toronto ...
- rm_invalid_file
import xlrd import time import sys import os import requests import sqlite3 import threading curPath ...
- 2017-2018-1 20179209《Linux内核原理与分析》第八周作业
Linux内核如何装载和启动一个可执行程 一.实验 1.1理解编译链接的过程和ELF可执行文件格式. 1.1.1编译链接过程 能用图说明的问题,就少用文字描述: 1.1.2ELF可执行文件 ELF可执 ...
- linux c编程:Posix消息队列
Posix消息队列可以认为是一个消息链表. 有足够写权限的线程可以往队列中放置消息, 有足够读权限的线程可以从队列中取走消息 在某个进程往一个队列写入消息前, 并不需要另外某个进程在该队列上等待消息的 ...
- linux c编程:进程控制(三)_exec函数
fork()函数通过系统调用创建一个与原来进程(父进程)几乎完全相同的进程(子进程是父进程的副本,它将获得父进程数据空间.堆.栈等资源的副本.注意,子进程持有的是上述存储空间的“副本”,这意味着父子进 ...
- 华为机试ACM(字符组合问题)
今晚做了华为的机试,3道ACM题,最后一道是实现从M个不同字符中任取N个字符的所有组合. eg: input:ABC 2 output:AB AC BC 第一个输入为字符串,第二个输入为组合的字符个数 ...
- full_case parallel_case学习心得
一般情况下,DC把case语句综合成选择器电路,但也可能把case语句综合成优先权译码电路.有时,优先权译码电路是不必要的,这是可以使用“// synopsys parallel_case”引导语句强 ...
- Yii2之事件处理
通过事件(Event)处理,可以在某个特定时刻执行指定的代码,可以解耦代码,同时也增加了可维护性,通常,事件在客户端软件中比较好理解,比如onClick,onFocus,当点击按钮,获取到焦点时执行指 ...
- ubuntu 安装 phpstorm
phpstorm是用JAVA开发的,所以在安装之前需要先安装jdksudo apt-get install default-jdk从官网上下载phpstorm 的linux版本 http://www. ...