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 ...
随机推荐
- laravel实现数据库读写分离配置或者多读写分离配置
config\database.php里 读写分离:'mysql' => array( 'read' => array( 'host' => '192.168.1.1', ), 'w ...
- [AngularJS] Exploring the Angular 1.5 .component() method
Angualr 1.4: .directive('counter', function counter() { return { scope: {}, restrict: 'EA', transclu ...
- [CSS3] Interactive Pseudo-Classes :link :visited :hover :active
The interactive pseudo-classes for links (and buttons) allow us to make sure the user knows what ele ...
- 如何实现数字lcd显示效果(原创)
如题,我最先想到的是找一种字体,然后来显示lcd的效果,但是字体又无法满足有空位的时候那个暗灰色的文字的效果,如下所示 就是前三位那些灰色的888,因为你设置数值的时候只能是从0-9的数字,而这灰色的 ...
- C++ STL set集合容器
汇总了一些set的常用语句,部分参考了这篇:http://blog.163.com/jackie_howe/blog/static/199491347201231691525484/ #include ...
- XML数据的读取—数据库配置文件
数据库配置文件(config.xml) <?xml version="1.0" encoding="utf-8"?> <configurati ...
- CSS 样式属性锦集
ul#nav > Li 只有一个大于号,是指应用了#nav这个ID的下一级元素的儿子辈Li 元素定义的内容符合这个CSS代码定义的样式,但是孙子辈Li元素定义的内容就不符合这个CSS代码样式了, ...
- Android让你的Toast变得炫酷
一.代码: app.gradle: dependencies{ compile 'com.sdsmdg.tastytoast:tastytoast:0.0.2'} java代码: TastyToast ...
- 关于android:configChanges小结
有段时间没更新博客了,做个音乐播放器遇到了坑,暂放来学习一个开源小项目
- char * 和 void *
POSIX.1 将 read函数的原型做了修改,经典的定义为 int read(int filedes, char *buf, unsigned nbytes); 修改为 ssize_t read(i ...