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生成树的更多相关文章

  1. 图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用

    图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 ...

  2. NOIP 2013 货车运输 最大生成树加DFS巧妙AC

    #include<set> #include<map> #include<cmath> #include<queue> #include<stac ...

  3. luogu p2330[SCOI05] 繁忙的都市——瓶颈生成树

    P2330 05四川 繁忙的都市 题目描述 城市C是一个非常繁忙的大都市,城市中的道路十分的拥挤,于是市长决定对其中的道路进行改造.城市C的道路是这样分布的:城市中有n个交叉路口,有些交叉路口之间有道 ...

  4. jstree动态生成树

    前篇文章简单介绍了静态生成树,这篇文章将通过后台把数据通过json形式传到前台,进行动态生成树. 本篇的程序所用框架为Spring MVC,可以很方便的通过controller层传json到前台. 前 ...

  5. jstree静态生成树并为树添加触发事件

    本章将介绍如何简单的使用jstree生成树(生成树的数据是静态的),并为树添加点击事件. 1. 建一个jsp页面,引入jquery.js(在其他js前引用),引入jstree所需的js,css文件(可 ...

  6. 【BZOJ1002】【FJOI2007】轮状病毒(生成树计数)

    1002: [FJOI2007]轮状病毒 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1766  Solved: 946[Submit][Status ...

  7. 【HDU 4305】Lightning(生成树计数)

    Problem Description There are N robots standing on the ground (Don't know why. Don't know how). Sudd ...

  8. PHP无限极分类生成树方法,无限分级

    你还在用浪费时间又浪费内存的递归遍历无限极分类吗,看了该篇文章,我觉得你应该换换了.这是我在OSChina上看到的一段非常精简的PHP无限极分类生成树方法,巧在引用,整理分享了. function g ...

  9. ACM:Pseudoforest-并查集-最大生成树-解题报

    Pseudoforest Time Limit:5000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit Status ...

随机推荐

  1. JS能力测评试题

    找出元素 item 在给定数组 arr 中的位置 function indexOf(arr, item) { return arr.indexOf(item); } function indexOf( ...

  2. 用endsWith()来限制图片的后缀名

    var a=document.getElementById('file-name'); var filename=a.value if(!a.endsWith('.jpg')||!a.endsWith ...

  3. jquery animate

    $(".logo").animate( { opacity: .25, //将不透明度逐渐变成.25 height: 0 //高度逐渐变成0 }, { duration: 1000 ...

  4. Java中迭代列表中数据时几种循环写法的效率比较

    Java中经常会用到迭代列表数据的情况,本文针对几种常用的写法进行效率比较.虽然网上已经有了类似的文章,但是对他们的结论并不认同. 常见的实现方法: 1.for循环: for(int i = 0; i ...

  5. JSP导出Excel文件

    和普通的查询数据差别是没有分页,response设置一下就是到处功能. window.location.href="${_base}/promoteConsume/exportExcel?& ...

  6. 单向链表JAVA代码

        //单向链表类 publicclassLinkList{       //结点类     publicclassNode{         publicObject data;         ...

  7. 小学生之SpringMVC

    1. Springmvc是什么? Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基 ...

  8. 安装VS2013的离线MSDN帮助文档

    作为vs的初学者,安装帮助文档有利于快速掌握.net的基本语法,对于摸索学习的同学帮助很大. VS2013和VS2012的帮助文档目前为止还是一样 下面是下载地址    http://www.micr ...

  9. 在winform程序中实现按照不同的角色或用户展现不同的页面

    SqlConnection cn = new SqlConnection();             cn.ConnectionString = "Data Source=192.168. ...

  10. Java类与类之间关系总结

    继承,依赖,关联,聚合,组合 一般来说依赖和关联是类似的,关联是强依赖,聚合和组合是一类,组合属于强聚合. 继承:一般是子类和父类之间的关系,关键字extends 依赖:可以这样记忆,做某件事必须要依 ...