• poj2728 Desert King


    最优比率生成树问题。

    是完全图要用prim。顺便学了一发dinkelbach。二分1700ms+ 迭代200ms+很优秀

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    int n;
    double X[1100],Y[1100],Z[1100];
    double cst[1100][1100],dis[1100][1100];
    
    double a[1100][1100],d[1100];
    bool v[1100];
    bool check(double mid)
    {
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++) if(i!=j)
                a[i][j]=cst[i][j]-mid*dis[i][j];
        
        memset(v,false,sizeof(v));
        memset(d,0x7f,sizeof(d));
        for(int i=1;i<n;i++)
        {
            int x=-1;
            for(int j=1;j<=n;j++)
                if(v[j]==false&&(x==-1||d[x]>d[j]))x=j;
            v[x]=true;
            for(int y=1;y<=n;y++)
                if(v[y]==false)d[y]=min(d[y],a[x][y]);
        }
        double ans=0;
        for(int i=2;i<=n;i++)ans+=d[i];
        return (ans<0)||(fabs(ans)<1e-8);
    }
    
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            if(n==0)break;
            
            for(int i=1;i<=n;i++)
                scanf("%lf%lf%lf",&X[i],&Y[i],&Z[i]);
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++) if(i!=j)
                {
                    cst[i][j]=fabs(Z[i]-Z[j]);
                    dis[i][j]=sqrt( (X[i]-X[j])*(X[i]-X[j])+(Y[i]-Y[j])*(Y[i]-Y[j]) );
                }
                
            double l=0.0,r=100000.0;
            while(r-l>1e-5)
            {
                double mid=(l+r)/2;
                if(check(mid))r=mid;
                else l=mid;
            }
            printf("%.3lf
    ",r);
        }
        return 0;
    }
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    int n;
    double X[1100],Y[1100],Z[1100];
    double cst[1100][1100],dis[1100][1100];
    
    double a[1100][1100],d[1100]; int p[1100];
    bool v[1100];
    double check(double mid)
    {
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++) if(i!=j)
                a[i][j]=cst[i][j]-mid*dis[i][j];
        
        memset(v,false,sizeof(v));
        memset(d,0x7f,sizeof(d));
        for(int i=1;i<n;i++)
        {
            int x=-1;
            for(int j=1;j<=n;j++)
                if(v[j]==false&&(x==-1||d[x]>d[j]))x=j;
            v[x]=true;
            for(int y=1;y<=n;y++)
                if(v[y]==false)
                {
                    if(d[y]>a[x][y])
                    {
                        d[y]=a[x][y];
                        p[y]=x;
                    }
                }
        }
        double sumc=0,sumd=0;
        for(int i=1;i<=n;i++)sumc+=cst[p[i]][i],sumd+=dis[p[i]][i];
        return sumc/sumd;
    }
    
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            if(n==0)break;
            
            for(int i=1;i<=n;i++)
                scanf("%lf%lf%lf",&X[i],&Y[i],&Z[i]);
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++) if(i!=j)
                {
                    cst[i][j]=fabs(Z[i]-Z[j]);
                    dis[i][j]=sqrt( (X[i]-X[j])*(X[i]-X[j])+(Y[i]-Y[j])*(Y[i]-Y[j]) );
                }
                
            double A=0;
            while(1)
            {
                double B=check(A);
                if(fabs(A-B)<1e-8)break;
                else A=B;
            }
            printf("%.3lf
    ",A);
        }
        return 0;
    }
  • 相关阅读:
    LeetCode——二叉搜索树中的中序后继 II
    一加 2020.10.13 笔试
    携程 2020.10.13 笔试
    中科曙光 2020.10.12 面试
    58 2020.10.11 笔试
    华为 2020.10.11 面试
    LeetCode——二叉搜索树中的顺序后继
    健网未来 2020.10.10 面试
    波特率
    PGA基础知识极简教程(4)从FIFO设计讲起之异步FIFO篇
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/9523948.html
Copyright © 2020-2023  润新知