COJ 0248 HDNOIP201408生成树
| HDNOIP201408生成树 |
| 难度级别: A; 编程语言:不限;运行时间限制:5000ms; 运行空间限制:262144KB; 代码长度限制:2000000B |
|
试题描述
|
|
|
|
输入
|
|
第一行包括两个整数V,E,表示图的度数和图的边数接下来E行,每行包括4 个整数v1,v2,a(v1,v2), b(v1,v2),表示图中的v1,v2 两点之间有一条权值为a(v1,v2), b(v1,v2)的边。顶点的下标从0 开始标记,即0<=v1,v2<V。
|
|
输出
|
|
仅一行,包含一个整数:F(T)的最小值。
|
|
输入示例
|
|
3 4
1 2 1 1 2 0 1 1 0 1 1 1 0 2 2 3 |
|
输出示例
|
|
4
|
|
其他说明
|
|
对于20%的数据,V<=10,E<=20
对于50%的数据,V<=50,E<=1000 对于100%的数据,V<=300,E<=10000,1 ≤a_((v1,v2)), b_((v1,v2))≤ 1000 |
题解:最小乘积生成树的板子。

设每个点有x,y两个权值,求一棵生成树,使得sigma(x[i])*sigma(y[i])最小。
设每棵生成树为坐标系上的一个点,sigma(x[i])为横坐标,sigma(y[i])为纵坐标。则问题转化为求一个点,使得xy=k最小。即,使过这个点的反比例函数y=k/x最接近坐标轴。
Step1:求得分别距x轴和y轴最近的生成树(点):A、B(分别按x权值和y权值做最小生成树即可)。
Step2:寻找一个在AB的靠近原点一侧的且离AB最远的生成树C,试图更新答案。
【怎么找????
——由于C离AB最远,所以S△ABC面积最大。
向量AB=(B.x - A.x , B.y - A.y)
向量AC= (C.x - A.x , C.y - A.y)
向量AB、AC的叉积(的二分之一)为S△ABC的面积(只不过叉积是有向的,是负的,所以最小化这个值,即为最大化面积)。
最小化:(B.x-A.x)*(C.y-A.y)-(B.y-A.y)*(C.x-A.x)
=(B.x-A.x)*C.y+(A.y-B.y)*C.x - A.y*(B.x-A.x)+A.x*(B.y-A.y)/*粗体为常数,不要管*/
所以将每个点的权值修改为 y[i]*(B.x-A.x)+(A.y-B.y)*x[i] 做最小生成树,找到的即是C。】
Step3:递归地分别往AC、BC靠近原点的一侧找。递归边界:该侧没有点了(即叉积大于等于零)。——The Solution By AutSky_JadeK(From SDOI).http://www.cnblogs.com/autsky-jadek/.
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#define PAU putchar(' ')
#define ENT putchar('\n')
using namespace std;
typedef long long ll;
const int maxn=+;
const int maxm=+;
const int inf=<<;
inline long long read(){
long long x=,sig=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') sig=-;ch=getchar();}
while(isdigit(ch)) x=*x+ch-'',ch=getchar();
return x*=sig;
}
inline void write(int x){
if(x==){putchar('');return;}if(x<) putchar('-'),x=-x;
int len=,buf[];while(x) buf[len++]=x%,x/=;
for(int i=len-;i>=;i--) putchar(buf[i]+'');return;
}
struct point{ll x,y;}ans;
point operator-(const point&a,const point&b){return(point){a.x-b.x,a.y-b.y};}
ll operator*(point a,point b){return a.x*b.y-a.y*b.x;}
bool operator<(point a,point b){return a.x*a.y<b.x*b.y||a.x*a.y==b.x*b.y&&a.x<b.x;}
struct edge{int u,v,x,y;ll w;}e[maxm];
bool operator<(edge a,edge b){return a.w<b.w;}
int n,m,fa[maxn];
int findset(int x){return x==fa[x]?x:fa[x]=findset(fa[x]);}
void setinit(){for(int i=;i<n;i++)fa[i]=i;return;}
point kruscal(){
point tmp=(point){,};setinit(),sort(e,e+m);
for(int i=;i<m;i++){
int u=findset(e[i].u),v=findset(e[i].v);
if(u!=v){
fa[u]=v;
tmp.x+=e[i].x;
tmp.y+=e[i].y;
}
}if(tmp<ans)ans=tmp;return tmp;
}
void solve(point a,point b){
for(int i=;i<m;i++)e[i].w=(b.x-a.x)*e[i].y+(a.y-b.y)*e[i].x;
point c=kruscal();if((a-c)*(b-c)<)solve(a,c),solve(c,b);return;
}
void init(){
n=read(),m=read();
for(int i=;i<m;i++){
e[i].u=read(),e[i].v=read();
e[i].x=read(),e[i].y=read();
}ans.x=ans.y=inf;
return;
}
void work(){
for(int i=;i<m;i++)e[i].w=e[i].x;
point a=kruscal();
for(int i=;i<m;i++)e[i].w=e[i].y;
point b=kruscal();
solve(a,b);
return;
}
void print(){
write(ans.x*ans.y);
return;
}
int main(){init();work();print();return ;}
COJ 0248 HDNOIP201408生成树的更多相关文章
- 图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用
图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 ...
- NOIP 2013 货车运输 最大生成树加DFS巧妙AC
#include<set> #include<map> #include<cmath> #include<queue> #include<stac ...
- luogu p2330[SCOI05] 繁忙的都市——瓶颈生成树
P2330 05四川 繁忙的都市 题目描述 城市C是一个非常繁忙的大都市,城市中的道路十分的拥挤,于是市长决定对其中的道路进行改造.城市C的道路是这样分布的:城市中有n个交叉路口,有些交叉路口之间有道 ...
- jstree动态生成树
前篇文章简单介绍了静态生成树,这篇文章将通过后台把数据通过json形式传到前台,进行动态生成树. 本篇的程序所用框架为Spring MVC,可以很方便的通过controller层传json到前台. 前 ...
- jstree静态生成树并为树添加触发事件
本章将介绍如何简单的使用jstree生成树(生成树的数据是静态的),并为树添加点击事件. 1. 建一个jsp页面,引入jquery.js(在其他js前引用),引入jstree所需的js,css文件(可 ...
- 【BZOJ1002】【FJOI2007】轮状病毒(生成树计数)
1002: [FJOI2007]轮状病毒 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 1766 Solved: 946[Submit][Status ...
- 【HDU 4305】Lightning(生成树计数)
Problem Description There are N robots standing on the ground (Don't know why. Don't know how). Sudd ...
- PHP无限极分类生成树方法,无限分级
你还在用浪费时间又浪费内存的递归遍历无限极分类吗,看了该篇文章,我觉得你应该换换了.这是我在OSChina上看到的一段非常精简的PHP无限极分类生成树方法,巧在引用,整理分享了. function g ...
- ACM:Pseudoforest-并查集-最大生成树-解题报
Pseudoforest Time Limit:5000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit Status ...
随机推荐
- python网上开发执行环境
http://www.tutorialspoint.com/execute_python_online.php
- Install Oracle 10g on Red Hat Linux 5.3 Step by Step
一.虚拟机配置 1. 虚拟机(VBox 4.3.12) 2. 配置虚拟机网卡网络.选择host-only.VirtualBox Host-Only Network网卡IP为设置为192.168.1.1 ...
- Android学习–Android app 语言切换功能
功能: app用户根据自己的语言喜好,设置app语言.语言设置只针对本app,并在下次启动应用时保留前一次启动设置. 更新语言: public static void changeAppLanguag ...
- Android实现计时与倒计时(限时抢购)的几种方法
在购物网站的促销活动中一般都有倒计时限制购物时间或者折扣的时间,这些都是如何实现的呢? 在一个安卓客户端项目中恰好遇到了类似的问题,一开始使用的是Timer与 TimerTask, 虽然此方法通用,但 ...
- diameter - degree problem
如今要构建一个网络模型,网络中的每一个节点最多和 d 个节点相连接, 且信息的传播从随意一个节点到另外随意一个节点的"最短路径" (路径依照单位路径算)都不能超过 k,问网络中最多 ...
- 使用truncate命令清空当前用户所有表的所有数据
--批量清空当前用户所有表的所有数据 declarev_sql varchar2(2000) ;CURSOR cur is select table_name from user_tables ord ...
- webform初识
webform是个bs结构的程序, winform 是个cs结构的程序: aspx 是由 网页和cs代码 构成的: aspx的网页控件是 有, 服务器控件和客户端控件组成的. 客户端控件,就是HTML ...
- unable to convert MySQL date/time value to System.DateTime
今天 用C# MySql做项目的时候 遇到了 unable to convert MySQL date/time value to System.DateTime 这样的异常错误,这个原因是因为:表里 ...
- 各版本IIS安装方法
各版本IIS安装方法 Windows 2000 V5.0 将操作系统安装光盘放入光驱,打开“控制面板”→“添加或删除程序”→“添加/删除 Windows 组件”,勾选“Internet信息服务(I ...
- ADB错误“more than one device and emulator”(转)
当我连着手机充电的时候,启动模拟器调试,执行ADB指令时,报错.C:\Users\gaojs>adb shellerror: more than one device and emulatorC ...
