zoukankan      html  css  js  c++  java
  • 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);
        }
    }
  • 相关阅读:
    Python语法入门之基本数据类型
    ASCII,GBK,和Unicode的UTF-8,UTF-16,UTF-32阐述
    为什么计算机只认识0和1?
    Intel万兆网卡82599linux驱动安装
    Django自定义分页器
    Django图片防盗链
    Django配置用户上传文件夹和暴露后端文件夹资源
    Django之TruncMonth截取日期作为新的虚拟字段使用
    第十一篇:auth模块
    第十篇:跨站请求伪造csrf
  • 原文地址:https://www.cnblogs.com/King-of-Dark/p/12826289.html
Copyright © 2011-2022 走看看