poj2728 二分优化
Posted king-of-dark
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj2728 二分优化相关的知识,希望对你有一定的参考价值。
题目大意:
给你一堆三维的点,每个点之间的距离是xy轴的欧式距离,代价是高度,问一颗最优比例生成树。这题是我很早之前做过的了,当初还非常非常菜,给大家看一下我的情况。
当初可真是年少无知啊,这个prim因为是稠密图,所以n方才能求生成树,很神奇啊,稠密图的最小生成树算法居然是o(e)的,不过还是很慢就是了。
后来这个题还有一次二分优化,就是说你二分得到的知识不仅仅是只有能或者不能,而是还存在着其他的信息。
你二分了一次之后还能得到一些有用的,就是你能拿到下一次可能的答案。
你从下一次的答案还能继续递推,这样可以更快速的跳过去。
具体的可以去学学01规划,这个trick感觉还可以。
ac代码(快的那个):
#include <queue> #include <math.h> #include <algorithm> #include <string.h> #include <iostream> #include <cstring> #include <stdio.h> #define clr(a) memset(a,0,sizeof a) using namespace std; typedef pair<double ,int> P; const int maxn=1000+10; const int inf=0x3f3f3f3f; double mm[maxn][maxn]; int n,heigh[maxn]; P m_t[maxn]; struct node { double wei,dis,cos; }; double dis(double a,double b,double c,double d) { return sqrt((a-c)*(a-c)+(b-d)*(b-d)); } bool used[maxn]; double J(double c) { clr(used); node lowcast[maxn]; for(int i=0;i<maxn;i++){ lowcast[i].wei=inf; } lowcast[0].wei=0; lowcast[0].dis=0; lowcast[0].cos=0; double dis_sum=0,cost_sum=0; while(1) { int k=-1,t_max=inf; for(int i=0;i<n;i++) { if(!used[i]&&lowcast[i].wei<t_max) { t_max=lowcast[i].wei; k=i; } } if(k==-1) break; used[k]=1; cost_sum+=lowcast[k].cos; dis_sum+=lowcast[k].dis; for(int i=0;i<n;i++) if(!used[i]&&lowcast[i].wei>abs(heigh[k]-heigh[i])-c*mm[k][i]){ lowcast[i].wei=abs(heigh[k]-heigh[i])-c*mm[k][i]; lowcast[i].cos=abs(heigh[k]-heigh[i]); lowcast[i].dis=mm[k][i]; } } return cost_sum/dis_sum; } int main() { while(1){ scanf("%d",&n); if(n==0) break; for(int i=0;i<n;i++) scanf("%lf%d%d",&m_t[i].first,&m_t[i].second,&heigh[i]); for(int i=0;i<n;i++)//n2 for(int j=i;j<n;j++) { mm[j][i]=mm[i][j]=dis(m_t[i].first,m_t[i].second,m_t[j].first,m_t[j].second); } double rate=0,t_rate; while(1) { t_rate=J(rate); if(abs(t_rate-rate)<0.00001){ rate=t_rate; break; } rate=t_rate; } printf("%.3lf ",rate); } }
以上是关于poj2728 二分优化的主要内容,如果未能解决你的问题,请参考以下文章
[POJ2976][POJ2728]01分数规划问题的二分答案解法
POJ 2728 JZYZOJ 1636 分数规划 最小生成树 二分 prim