poj2728 (01参数规划,最优化率生成树,二分)

本文探讨了参数规划问题中利用二分搜索优化生成树的方法,通过重构距离矩阵,实现精确求解。重点介绍了如何通过调整参数,有效提升算法效率并避免常见错误,如WA和TLE。实例分析了距离计算、二分搜索策略及其在生成树算法中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


      这题01参数规划,其实就是二分,最优率生成树,但是精度卡的太死了,,要么WA,要么TLE。
      二分 重新构图 : graph[i][j]=fabs(dot[i].h-dot[j].h)-mid*dis(dot[i].x,dot[i].y,dot[j].x,dot[j].y);


#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include <cstdio>
using namespace std;
#define MAX 1001
#define INF 1000000000
struct node
{

    double x,y,h;
}dot[MAX];


inline double dis(double x1,double y1,double x2,double y2)
{

    return sqrt( (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1) );
}


double graph[MAX][MAX];

inline void creat(int n,double l)
{
    int i,j;
    for(i=1;i<=n;i++)
    {

        for(j=1;j<=n;j++)
        {

            graph[i][j]=fabs(dot[i].h-dot[j].h)-l*dis(dot[i].x,dot[i].y,dot[j].x,dot[j].y);
        }
    }
}

inline double prim(double graph[MAX][MAX],int n)
{
    bool visit[MAX]={0};
    int mark;
    double dis[MAX];
    double ans=0;
    int i,j;
    visit[1]=true;
    for(i=1;i<=n;i++)
        dis[i]=graph[1][i];
    for(i=1;i<n;i++)
    {

        int minnum=INF;
        for(j=1;j<=n;j++)
        {

            if(!visit[j]&&dis[j]<=minnum)
            {
                minnum=dis[j];
                mark=j;
            }
        }
        visit[mark]=true;
        ans+=dis[mark];
        for(j=1;j<=n;j++)
        {
            if(!visit[j]&&graph[mark][j]<dis[j])
                dis[j]=graph[mark][j];
        }

    }
    return ans;
}


int main()
{

    int i,j;
    int n;
    double res;
    while(scanf("%d",&n))
    {

        if(n==0)
            break;
        for(i=1;i<=n;i++)
        {
            scanf("%lf%lf%lf",&dot[i].x,&dot[i].y,&dot[i].h);
        }
        double front,rear;
        front=0;
        rear=100;//这个地方有点悬。。。
        double mid;
        double pre=0.0;
        while(front<=rear)
        {

            mid=(front+rear)/2;
            creat(n,mid);
            res=prim(graph,n);
            if(fabs(res-pre)<=0.0005)
                break;
            else if(res>0.0005)
                front=mid;
            else
                rear=mid;
        }
        printf("%.3lf\n",mid);
    }
    return 0;
}





                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值