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/.

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<cstring>
 7 #define PAU putchar(‘ ‘)
 8 #define ENT putchar(‘\n‘)
 9 using namespace std;
10 typedef long long ll;
11 const int maxn=300+10;
12 const int maxm=20000+10;
13 const int inf=1<<28;
14 inline long long read(){
15     long long x=0,sig=1;char ch=getchar();
16     while(!isdigit(ch)){if(ch==‘-‘) sig=-1;ch=getchar();}
17     while(isdigit(ch)) x=10*x+ch-‘0‘,ch=getchar();
18     return x*=sig;
19 }
20 inline void write(int x){
21     if(x==0){putchar(‘0‘);return;}if(x<0) putchar(‘-‘),x=-x;
22     int len=0,buf[15];while(x) buf[len++]=x%10,x/=10;
23     for(int i=len-1;i>=0;i--) putchar(buf[i]+‘0‘);return;
24 }
25 struct point{ll x,y;}ans;
26 point operator-(const point&a,const point&b){return(point){a.x-b.x,a.y-b.y};}
27 ll operator*(point a,point b){return a.x*b.y-a.y*b.x;}
28 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;}
29 struct edge{int u,v,x,y;ll w;}e[maxm];
30 bool operator<(edge a,edge b){return a.w<b.w;}
31 int n,m,fa[maxn];
32 int findset(int x){return x==fa[x]?x:fa[x]=findset(fa[x]);}
33 void setinit(){for(int i=0;i<n;i++)fa[i]=i;return;}
34 point kruscal(){
35     point tmp=(point){0,0};setinit(),sort(e,e+m);
36     for(int i=0;i<m;i++){
37         int u=findset(e[i].u),v=findset(e[i].v);
38         if(u!=v){
39             fa[u]=v;
40             tmp.x+=e[i].x;
41             tmp.y+=e[i].y;
42         }
43     }if(tmp<ans)ans=tmp;return tmp;
44 }
45 void solve(point a,point b){
46     for(int i=0;i<m;i++)e[i].w=(b.x-a.x)*e[i].y+(a.y-b.y)*e[i].x;
47     point c=kruscal();if((a-c)*(b-c)<0)solve(a,c),solve(c,b);return;
48 }
49 void init(){
50     n=read(),m=read();
51     for(int i=0;i<m;i++){
52         e[i].u=read(),e[i].v=read();
53         e[i].x=read(),e[i].y=read();
54     }ans.x=ans.y=inf;
55     return;
56 }
57 void work(){
58     for(int i=0;i<m;i++)e[i].w=e[i].x;
59     point a=kruscal();
60     for(int i=0;i<m;i++)e[i].w=e[i].y;
61     point b=kruscal();
62     solve(a,b);
63     return;
64 }
65 void print(){
66     write(ans.x*ans.y);
67     return;
68 }
69 int main(){init();work();print();return 0;}
时间: 2024-10-05 20:14:16

COJ 0248 HDNOIP201408生成树的相关文章

实验 快速生成树配置

[实验名称] 快速生成树协议 RSTP 的配置. [实验目的] 理解快速生成树协议 RSTP 的工作原理,掌握如何在交换机上配置快速生成树. [背景描述] 某学校为了开展计算机教学和网络办公,建立了一个计算机教室和一个校办公区,这两 处的计算机网络通过两台交换机互连组成内部校园网,为了提高网络的可靠性,网络管理员 用 2 条链路将交换机互连,现要在交换机上做适当配置,使网络避免环路. [需求分析] 两台交换机以双链路互联,需要在启用 RSTP 避免环路的同时,提供链路的冗余备份功 能. [实验拓

STP生成树协议的分析总结

一,STP概述 STP(Spanning Tree Protocol,生成树协议)是有应用于交换机之间的防环的.功能是用来防环的. 基本原理: 通过在交换机之间传递一种特殊的协议报文,网桥协议数据单元(BPDU),来确定网络的拓扑结构.BPDU有两种,一种是配置BPDU(configuration BPDU),一种TC BPDU(拓扑变更BPDU). 前者是用于计算无环的生成树的:后者是用于在二层网络拓扑发生变化时产生用来缩短MAC表项的刷新时间的(由默认的300s--->15s) 分类: ST

生成树的基本调整

1.调整vlan的优先级:switch<config># spanning vlan X priority Y       将vlan X的优先级调整为Y,Y是4096的倍数 2.实施端口快速即portfast: 通常情况下,如果生成树中端口状态发生改变,引起生成树从新计算,那么需要大约30s收敛,这是不能承受的. 所以,我们要在连接主机的端口上实施portfast以保证生成树的稳定,它跳过了端口从LIS到LRN,LRN到FWD的过程,收敛速度很快 具体操作有两种,第一种:在所有需要的接口上单

UVa 1395 苗条的生成树(Kruskal+并查集)

https://vjudge.net/problem/UVA-1395 题意: 给出一个n结点的图,求苗条度(最大边减最小边的值)尽量小的生成树. 思路: 主要还是克鲁斯卡尔算法,先仍是按权值排序,对于一个连续的边集区间[L,R],如果这些边使得n个点全部连通,则一定存在一个苗条度不超过W[R]-W[L]的生成树.从小到大枚举L,对于每个L,从小到大枚举R. 这道题目我一直超时,最后发现数组开小了,我一直以为数组开小了肯定会出来Runtime error的... 1 #include<iostr

POJ 1679 The Unique MST(次短生成树)

Language: Default The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 29098   Accepted: 10404 Description Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spanning Tree): Consider

【bzoj 2467】[中山市选2010]生成树(数论--排列组合)

题目:有一种图形叫做五角形圈.一个五角形圈的中心有1个由n个顶点和n条边组成的圈.在中心的这个n边圈的每一条边同时也是某一个五角形的一条边,一共有n个不同的五角形.这些五角形只在五角形圈的中心的圈上有公共的顶点.现在给定一个n五角形圈,你的任务就是求出n五角形圈的不同生成树的数目.还记得什么是图的生成树吗?一个图的生成树是保留原图的所有顶点以及顶点的数目减去一这么多条边,从而生成的一棵树.注意:在给定的n五角形圈中所有顶点均视为不同的顶点. 解法:题目是问使这 N 五角形圈生成树的种数.而生成树

交换机生成树协议配置

交换机生成树协议配置 一.实验目的 理解生成树STP及快速生成树RSTP的工作原理,掌握如何在交换机上配置快速生成树协议. 二.实验原理 各公司都在寻找1天24小时,1周7天都能正常运行的计算机网络.达到100%正常运行是几乎不可能的,但是99.999%(即5个9)的可靠性则是一些组织设定的目标.这意味着每30年才有1天的故障时间,平均4000天才有1小时的故障时间,平均每年只有5.25分钟的故障时间.达到99.999%的可靠性的目标需要极端可靠的网络.网络的可靠性来源于可靠的设备和可以容忍故障

快速生成树配置

实验名称:端口聚合配置 实验目的:理解端口聚合的工作原理,掌握如何在交换机上配置端口聚合. 实验原理:端口聚合(Aggregate-port)又称链路聚合,是指两台交换机之间在物理上将多个端口 连接起来,将多条链路聚合成一条逻辑链路.从而增大链路带宽,解决交换网络中因带宽引 起的网络瓶颈问题.多条物理链路之间能够相互冗余备份,其中任意一条链路断开,不会影 响其他链路的正常转发数据. 端口聚合遵循 IEEE 802.3ad 协议的标准. 实验设备:两台交换机(三层二层各一台),两台电脑(配置生成树

实验六 快速生成树配置

1.准备工作: 工具:1台3层交换机,1台2层交换机,网线 (1)      开始 --> 控制面板 --> 程序 --> 程序和功能 --> 打开或关闭Windows功能 --> 勾选Telnet客户端 (2)      开始 --> 运行程序:cmd --> telnet 172.28.15.104 2006(打开其中一台交换机) 2.配置3层交换机IP和Trunk 3.启用RSTP 4.指定3层交换机为根网桥 5.查看生成树的配置 6.打开机柜,连接第2台交