树(最小乘积生成树,克鲁斯卡尔算法):BOI timeismoney
The NetLine company wants to offer broadband internet to N towns. For this, it suffices to construct
a network of N-1 broadband links between the towns, with the property that a message can travel
from any town to any other town on this network. NetLine has already identified all pairs of towns
between which a direct link can be constructed. For each such possible link, they know the cost and
the time it would take to construct the link.
The company is interested in minimizing both the total amount of time (links are built one at a time)
and the total amount of money spent to build the entire network. Since they couldn’t decide among
the two criteria, they decided to use the following formula to evaluate the value of a network:
SumTime = sum of times spent to construct the chosen links
SumMoney = sum of the money spent to construct the chosen links
V = SumTime * SumMoney
Task
Find a list of N-1 links to build, which minimizes the value V.
Description of input
The first line of input contains integers N – the number of towns and M – the number of pairs of
towns which can be connected. The towns are numbered starting from 0 to N-1. Each of the next M
lines contain four integers x, y, t and c – meaning town x can be connected to town y in time t and
with cost c.
Description of output
In the first line of output print two numbers: the total time (SumTime) and total money (Sum-
Money) used in the optimal solution (the one with minimal value V), separated by one space. The
next N-1 lines describe the links to be constructed. Each line contains a pair of numbers (x,y) describing
a link to be build (which must be among the possible links described in the input file). The
pairs can be printed out in any order. When multiple solutions exist, you may print any of them.
Constraints
· 1 ≤ N ≤ 200
· 1 ≤ M ≤ 10 000
· 0 ≤ x,y ≤ N-1
· 1 ≤ t,c ≤ 255
· One test has M = N - 1
· 40% of the tests will have for each possible link t = c
Example
timeismoney.in
5 7
0 1 161 79
0 2 161 15
0 3 13 153
1 4 142 183
2 4 236 80
3 4 40 241
2 1 65 92
timeismoney.out
279 501
2 1
0 3
0 2
3 4
方案啥的很好解决,就不写了。
和HNOI2014画框有类似的思想。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn=;
const int maxm=;
int fa[maxn],a[maxm],b[maxm];
int u[maxm],v[maxm],n,m; struct Node{
int x,y,z,id;
Node(int a=,int b=,int c=,int d=){
x=a;y=b;z=c;id=d;
}
friend bool operator <(Node a,Node b){
return a.z<b.z;
}
}p[maxm]; struct Point{
int x,y;
Point(int a=,int b=){
x=a;y=b;
}
friend bool operator ==(Point a,Point b){
return a.x==b.x&&a.y==b.y;
}
}lo,hi; int Find(int x){
return fa[x]==x?x:fa[x]=Find(fa[x]);
} Point Get_Ans(){
sort(p+,p+m+);Point ret(,);
for(int i=;i<=n;i++)fa[i]=i;
for(int i=;i<=m;i++){
int x=p[i].x,y=p[i].y;
if(Find(x)!=Find(y)){
ret.x+=a[p[i].id];
ret.y+=b[p[i].id];
fa[Find(y)]=Find(x);
}
}
return ret;
} Point Solve(Point l,Point r){
for(int i=;i<=m;i++)
p[i]=Node(u[i],v[i],b[i]*(r.x-l.x)-a[i]*(r.y-l.y),i);
Point mid=Get_Ans();
if(mid==l||mid==r)return l.x*l.y<r.x*r.y?l:r;
l=Solve(l,mid);r=Solve(mid,r);
return l.x*l.y<r.x*r.y?l:r;
} int main(){
freopen("timeismoney.in","r",stdin);
freopen("timeismoney.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++){
scanf("%d%d",&u[i],&v[i]);u[i]+=;v[i]+=;
scanf("%d%d",&a[i],&b[i]);
} for(int i=;i<=m;i++)p[i]=Node(u[i],v[i],a[i],i);lo=Get_Ans();
for(int i=;i<=m;i++)p[i]=Node(u[i],v[i],b[i],i);hi=Get_Ans();
Point ans=Solve(lo,hi);
printf("%d %d\n",ans.x,ans.y);
return ;
}
树(最小乘积生成树,克鲁斯卡尔算法):BOI timeismoney的更多相关文章
- 【最小乘积生成树】bzoj2395[Balkan 2011]Timeismoney
设每个点有x,y两个权值,求一棵生成树,使得sigma(x[i])*sigma(y[i])最小. 设每棵生成树为坐标系上的一个点,sigma(x[i])为横坐标,sigma(y[i])为纵坐标.则问题 ...
- 【算法】最小乘积生成树 & 最小乘积匹配 (HNOI2014画框)
今天考试的时候果然题目太难于是我就放弃了……转而学习了一下最小乘积生成树. 最小乘积生成树定义: (摘自网上一篇博文). 我们主要解决的问题就是当k = 2时,如何获得最小的权值乘积.我们注意到一张图 ...
- 最小生成树之Kruskal(克鲁斯卡尔)算法
学习最小生成树算法之前我们先来了解下下面这些概念: 树(Tree):如果一个无向连通图中不存在回路,则这种图称为树. 生成树 (Spanning Tree):无向连通图G的一个子图如果是一颗包含G的所 ...
- 图->连通性->最小生成树(克鲁斯卡尔算法)
文字描述 上一篇博客介绍了最小生成树(普里姆算法),知道了普里姆算法求最小生成树的时间复杂度为n^2, 就是说复杂度与顶点数无关,而与弧的数量没有关系: 而用克鲁斯卡尔(Kruskal)算法求最小生成 ...
- 最小生成树--克鲁斯卡尔算法(Kruskal)
按照惯例,接下来是本篇目录: $1 什么是最小生成树? $2 什么是克鲁斯卡尔算法? $3 克鲁斯卡尔算法的例题 摘要:本片讲的是最小生成树中的玄学算法--克鲁斯卡尔算法,然后就没有然后了. $1 什 ...
- prim算法,克鲁斯卡尔算法---最小生成树
最小生成树的一个作用,就是求最小花费.要在n个城市之间铺设光缆,主要目标是要使这 n 个城市的任意两个之间都可以通信,但铺设光缆的费用很高,且各个城市之间铺设光缆的费用不同,因此另一个目标是要使铺设光 ...
- HDU5697 刷题计划 dp+最小乘积生成树
分析:就是不断递归寻找靠近边界的最优解 学习博客(必须先看这个): 1:http://www.cnblogs.com/autsky-jadek/p/3959446.html 2:http://blog ...
- 贪心算法(Greedy Algorithm)之最小生成树 克鲁斯卡尔算法(Kruskal's algorithm)
克鲁斯卡尔算法(Kruskal's algorithm)是两个经典的最小生成树算法的较为简单理解的一个.这里面充分体现了贪心算法的精髓.大致的流程能够用一个图来表示.这里的图的选择借用了Wikiped ...
- hdu 1233(还是畅通project)(prime算法,克鲁斯卡尔算法)(并查集,最小生成树)
还是畅通project Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tota ...
随机推荐
- Linux网络基础
为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/SJQ. http://www.cnblogs.com/shijiaqi1066/p/3840284.html ...
- JS 模拟C# 字符串格式化操作
/*** ** 功能: 字符串格式化替换操作 ***/ String.prototype.format = function () { var args = arguments; return thi ...
- Adb connect监听指定的主机和端口/Adb监听Visual Studio Emulator for Android模拟器
语法: adb connect <host>[:<port>] 使用实例: adb connect //如果连接成功则返回 connected to 说明 在使用Visual ...
- java_设计模式_单例模式_Singleton Pattern(2016-08-04)
概念: 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 适用场景: 在计算机系统中,线程池.缓存.日志对象.对话框.打印机.显卡的驱动程序对象常被设计成单例.这些应用都或多或 ...
- HDU 3359 Kind of a Blur(高斯消元)
题意: H * W (W,H <= 10) 的矩阵A的某个元素A[i][j],从它出发到其他点的曼哈顿距离小于等于D的所有值的和S[i][j]除上可达点的数目,构成了矩阵B.给定矩阵B,求矩阵A ...
- windows core audio apis
这个播放流程有一次当初不是很理解,做个记录,代码中的中文部分,原文档是有解释的:To move a stream of rendering data through the endpoint buff ...
- js 实现tab选项卡
最近一直在研究js 如果不及时复习的话前边学到的东西很快就会忘掉,所以把前段时间的一个简单的tab选项卡的思路写出来也算复习了一下吧, 第一步:先把布局写出来: <div id="d ...
- Bootstrap_表单_表单提示信息
平常在制作表单验证时,要提供不同的提示信息.在Bootstrap框架中也提供了这样的效果.使用了一个"help-block"样式,将提示信息以块状显示,并且显示在控件底部. < ...
- 我的css reset
@charset "utf-8"; /*reset*/ body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,f ...
- Javascript 访问网页弹出qq
先在网页的正文结束位置 加上引用代码 代码如下 <SCRIPT type="text/javascript" src="/QQ.js"></S ...