• poj 2728 Desert King 夜


    http://poj.org/problem?id=2728

    分数规划+二分   此题的图过于稠密 需要用prime 找最小生成树

    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<string.h>
    
    using namespace std;
    
    const double eps=1e-5;
    const int N=1001;
    const double M=10000000000.0;
    struct node
    {
        int x,y;
        int h;
    }mem[N];//输入点和高度
    double d[N][N];//两点间 距离
    int cost[N][N];//高度差
    bool had[N];
    double dist[N];
    int n,m;
    double findd(int i,int j)//返回距离
    {
        return sqrt(1.0*(mem[i].x-mem[j].x)*(mem[i].x-mem[j].x)+
                    1.0*(mem[i].y-mem[j].y)*(mem[i].y-mem[j].y));
    }
    bool prime(double L)//求最小生成树
    {
        double ans=0.0;
        memset(had,false,sizeof(had));
        had[1]=true;
        for(int i=2;i<=n;++i)
        dist[i]=cost[1][i]-L*d[1][i];
        for(int w=1;w<n;++w)
        {
            double MIN=M;
            int k=-1;
            for(int i=2;i<=n;++i)
            {
                if(!had[i]&&dist[i]<MIN)
                {
                    MIN=dist[i];
                    k=i;
                }
            }
            ans+=MIN;
            had[k]=true;
            for(int i=2;i<=n;++i)
            {
                if(!had[i]&&cost[k][i]-L*d[k][i]<dist[i])
                {
                    dist[i]=cost[k][i]-L*d[k][i];
                }
            }
        }
        if(ans>0.0)
        return true;
        return false;
    
    }
    int main()
    {
        //freopen("data.txt","r",stdin);
        while(scanf("%d",&n)!=EOF)
        {
            if(n==0)
            break;
            for(int i=1;i<=n;++i)
            scanf("%d %d %d",&mem[i].x,&mem[i].y,&mem[i].h);
            for(int i=1;i<=n;++i)
            for(int j=i+1;j<=n;++j)
            {
                cost[i][j]=cost[j][i]=abs(mem[i].h-mem[j].h);//求花费
                d[i][j]=d[j][i]=findd(i,j);//求距离
            }
            double l=0.0,r=100.0;
            while(r-l>=eps)//二分缩紧
            {
                double mid=(l+r)/2.0;
                if(prime(mid))
                l=mid;
                else
                r=mid;
            }
            printf("%.3f\n",l);
        }
        return 0;
    }
    

      

  • 相关阅读:
    C语言I博客作业05
    C语言I博客作业04
    C语言II博客作业04
    C语言II博客作业03
    C语言II—作业02
    C语言II博客作业01
    学期总结
    C语言I博客作业08
    C语言I博客作业07
    C语言I博客作业06
  • 原文地址:https://www.cnblogs.com/liulangye/p/2625200.html
Copyright © 2020-2023  润新知