POJ 2728 JZYZOJ 1636 分数规划 最小生成树 二分 prim

http://172.20.6.3/Problem_Show.asp?id=1636

复习了prim,分数规划大概就是把一个求最小值或最大值的分式移项变成一个可二分求解的式子。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<cstdlib>
 7 using namespace std;
 8 const int maxn=1100;
 9 const double eps=0.0001;
10 int n;
11 long long c[maxn][3]={};
12 double e[maxn][maxn]={};
13 double t[maxn][maxn]={};
14 double w[maxn][maxn]={},k[maxn]={};
15 bool vis[maxn]={};
16 inline long long mabs(long long x){ return x>0?x:-x; }
17 inline long long sqr(long long x){ return x*x; }
18 bool ke(double v){
19     memset(vis,0,sizeof(vis));
20     for(int i=1;i<=n;i++){
21         for(int j=i;j<=n;j++){
22             w[i][j]=w[j][i]=t[i][j]-v*e[i][j];
23         }
24     }vis[1]=1;double fla=0;
25     for(int i=1;i<=n;i++){
26         k[i]=w[1][i];
27     }
28     for(int i=1;i<n;++i){
29         int u=-1;
30         for(int j=1;j<=n;++j){
31             if(!vis[j])
32                 if(u==-1||k[j]<k[u])u=j;
33         }
34         fla+=k[u];vis[u]=1;
35         for(int j=1;j<=n;++j){
36             if(!vis[j])
37                 if(w[u][j]<k[j])k[j]=w[u][j];
38         }
39     }
40     return fla<=0;
41 }
42 double doit(double l,double r){
43     while(r-l>eps){
44         double mid=(l+r)/2;
45         if(ke(mid))r=mid;
46         else l=mid+eps;
47     }
48     return l;
49 }
50 int main(){
51     //freopen("wtf.in","r",stdin);
52     scanf("%d",&n);
53     for(int i=1;i<=n;i++){
54         scanf("%lld%lld%lld",&c[i][0],&c[i][1],&c[i][2]);
55     }
56     for(int i=1;i<=n;i++){
57         for(int j=i;j<=n;j++){
58             e[i][j]=sqrt((double)(sqr(c[i][0]-c[j][0])+sqr(c[i][1]-c[j][1])));
59             t[i][j]=(double)mabs(c[i][2]-c[j][2]);
60             e[j][i]=e[i][j];t[j][i]=t[i][j];
61         }
62     }printf("%.3f",doit(1,100));
63     return 0;
64 }

原文地址:https://www.cnblogs.com/137shoebills/p/8350620.html

时间: 2024-10-31 10:35:58

POJ 2728 JZYZOJ 1636 分数规划 最小生成树 二分 prim的相关文章

poj 2976 基础01分数规划

这个题算是01分数规划的最基本的应用了, 01分数规划是给你n对数(a1, b1)....(an, bn), 然后让你选择一些数对, 使得sigma(ai)/sigma(bi)最大.这里附上讲解一份, http://blog.csdn.net/hhaile/article/details/8883652, 代码如下: #include <cstdio> #include <cstring> #include <algorithm> #include <iostre

poj 2976(01分数规划

题目:每门课有实际成绩a和总成绩b,要求去掉k门课后能得到的平均成绩的最大值. 思路:裸的分数规划题.一个非常经典的解决问题的思路就是把求值变为判定问题,然后进行2分,分数规划就是这类思想的一个应用.. 具体讲解参考此文章:http://blog.csdn.net/hhaile/article/details/8883652 /* * @author: Cwind * http://www.cnblogs.com/Cw-trip/ * 蒟蒻只能做几个水题.. */ //#pragma comme

POJ 3621(0/1分数规划,二分) Sightseeing Cows

题意 给一个n个点m条边的图,每一个点和每一条边都有权值.现在要找一个环的点权和/边权和最大,求这个最大值. 思路 SPFA+二分 题目的关系式:点权和/边权和 <= ans 转换一下就变成 ans*边权和 - 点权和 >= 0; 二分答案,然后用SPFA去check是否存在一个负权回路. 参考code: /* #pragma warning (disable: 4786) #pragma comment (linker, "/STACK:0x800000") */ #in

POJ 2728 Desert King(最优比率生成树 01分数规划)

http://poj.org/problem?id=2728 题意: 在这么一个图中求一棵生成树,这棵树的单位长度的花费最小是多少? 思路: 最优比率生成树,也就是01分数规划,二分答案即可,题目很简单,因为这题是稠密图,所以用prim算法会好点. 1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<vector>

POJ2728 最小比率生成树/0-1分数规划/二分/迭代(迭代不会)

用01分数规划 + prime + 二分 竟然2950MS惊险的过了QAQ 前提是在TLE了好几次下过的 = = 题目意思:有n个村庄,村庄在不同坐标和海拔,现在要对所有村庄供水,只要两个村庄之间有一条路即可,建造水管距离为坐标之间的欧几里德距离,费用为海拔之差,现在要求方案使得费用与距离的比值最小,很显然,这个题目是要求一棵最优比率生成树. 解题思路: 对答案进行二分,当把代进去的答案拿来算最小生成树的时候,一旦总路径长度为0,就是需要的答案. 0-1规划是啥? 概念有带权图G, 对于图中每条

【POJ3621】Sightseeing Cows 分数规划

[POJ3621]Sightseeing Cows 题意:在给定的一个图上寻找一个环路,使得总欢乐值(经过的点权值之和)/ 总时间(经过的边权值之和)最大. 题解:显然是分数规划,二分答案ans,将每条边的权值变成(ans*边权-2*起始点点权),然后我们希望找出一个环,使得环上的总边权<0 (一开始我把题意理解错了,题中给的是单向边,我把它当成是双向边+每条边只能走一次了~,想出一堆做法都接连pass掉) 然后就直接用SPFA判负环就好了嘛!由于原图不一定联通,所以一开始就把所有点都入队就完事

luogu3778/bzoj4898 商旅 (floyd+分数规划+spfa)

首先floyd求出来每两点间的最短距离,然后再求出来从某点买再到某点卖的最大收益 问题就变成了找到一个和的比值最大的环 所以做分数规划,二分出来那个答案r,把边权变成w[i]-r*l[i],再做spfa判正环就行了 (本来想偷懒用floyd判正环,结果T了) 1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define CLR(a,x) memset(a,x,sizeof(a)) 4 using namespace s

[例题/总结]0/1分数规划

[TOC] ##一.总述 0/1分数规划是专门解决0/1分数规划模型的一种算法~~(废话)~~.所以说0/1分数规划模型是什么呢?给定整数{\(a_1,a_2,a_3,...,a_n\)},{\(b_1,b_2,b_3,...,b_n\)}从中选出若干对数,使得它们各自和的比值最大.公式如下: \(\frac{\sum_{p=1}^{n}a_p\times x_p}{\sum_{p=1}^{n}b_p\times x_p}(x_p=1,0)\) ##二.实现原理 那么我们用什么方法可以求出这样一

poj 2728 Desert King(最优比率生成树,01分数规划)

http://poj.org/problem?id=2728 大致题意:有n个村庄,输入每个村庄的位置和高度,这n个村庄要连在一起,村与村之间的长度为他们之间的欧几里得距离,花费是两村之间的高度差,要求连在一起的花费和与距离和之比的最小值. 思路:明显的最优比率生成树.二分答案λ,每条边重新赋权c[i] - λd[i] ,因为要求比值最小,那么对于所有的生成树,它们的f[λ]必须>=0,所以只需求得基于最小生成树的f'[λ],当f'[λ] = 0时即找到了正解λ*. 二分: #include <