• POJ 2728 Desert King


    POJ_2728

        最优比率生成树问题,黑书上有详细的介绍,在求的时候可以直接二分K,也可以先假定一个K然后求得一个新的K,如此反复迭代下去。

        对于这个题而言,如果直接二分的话,大概二分50次就可以保证精度了,而迭代的话大概10次就可以保证精度了,所以迭代的效率还是高一些。

    View Code 直接二分
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<math.h>
    #define MAXD 1010
    #define INF 0x3f3f3f3f
    using namespace std;
    int N, vis[MAXD];
    double dis[MAXD], x[MAXD], y[MAXD], z[MAXD], bet[MAXD][MAXD];
    double sqr(double x)
    {
        return x * x;
    }
    void init()
    {
        int i, j;
        for(i = 0; i < N; i ++)
            scanf("%lf%lf%lf", &x[i], &y[i], &z[i]);
        for(i = 0; i < N; i ++)
            for(j = i + 1; j < N; j ++)
                bet[i][j] = bet[j][i] = sqrt(sqr(x[i] - x[j]) + sqr(y[i] - y[j]));
    }
    double prim(double K)
    {
        int i, j, k;
        double m, ans = 0, t;
        memset(vis, 0, sizeof(vis));
        fill(dis, dis + N, INF);
        dis[0] = 0;
        for(i = 0; i < N; i ++)
        {
            m = INF;
            for(j = 0; j < N; j ++)
                if(!vis[j] && dis[j] < m)
                    m = dis[k = j];
            vis[k] = 1;
            ans += dis[k];
            for(j = 0; j < N; j ++)
                if(!vis[j] && (t = fabs(z[k] - z[j]) - K * bet[k][j]) < dis[j])
                    dis[j] = t;
        }
        return ans;
    }
    void solve()
    {
        int i;
        double min = 0, max = INF, mid, ans;
        for(i = 0; i < 50; i ++)
        {
            mid = (min + max) / 2;
            ans = prim(mid);
            if(ans < 0)
                max = mid;
            else
                min = mid;
        }
        printf("%.3f\n", mid);
    }
    int main()
    {
        for(;;)
        {
            scanf("%d", &N);
            if(!N)
                break;
            init();
            solve();
        }
        return 0;
    }
    View Code 迭代求解
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<math.h>
    #define MAXD 1010
    #define INF 0x3f3f3f3f
    using namespace std;
    int N, vis[MAXD], pre[MAXD];
    double dis[MAXD], x[MAXD], y[MAXD], z[MAXD], bet[MAXD][MAXD];
    double sqr(double x)
    {
        return x * x;
    }
    void init()
    {
        int i, j;
        for(i = 0; i < N; i ++)
            scanf("%lf%lf%lf", &x[i], &y[i], &z[i]);
        for(i = 0; i < N; i ++)
            for(j = i; j < N; j ++)
                bet[i][j] = bet[j][i] = sqrt(sqr(x[i] - x[j]) + sqr(y[i] - y[j]));
    }
    double prim(double K)
    {
        int i, j, k;
        double m, zt = 0, lt = 0, t;
        memset(vis, 0, sizeof(vis));
        fill(dis, dis + N, INF);
        dis[0] = 0, pre[0] = 0;
        for(i = 0; i < N; i ++)
        {
            m = INF;
            for(j = 0; j < N; j ++)
                if(!vis[j] && dis[j] < m)
                    m = dis[k = j];
            vis[k] = 1;
            lt += bet[pre[k]][k], zt += fabs(z[pre[k]] - z[k]);
            for(j = 0; j < N; j ++)
                if(!vis[j] && (t = fabs(z[k] - z[j]) - K * bet[k][j]) < dis[j])
                    dis[j] = t, pre[j] = k;
        }
        return zt / lt;
    }
    void solve()
    {
        int i;
        double ans = 0;
        for(i = 0; i < 10; i ++)
            ans = prim(ans);
        printf("%.3f\n", ans);
    }
    int main()
    {
        for(;;)
        {
            scanf("%d", &N);
            if(!N)
                break;
            init();
            solve();
        }
        return 0;
    }
  • 相关阅读:
    类的嵌套
    一种设计模式--单例模式
    python中的类(二)
    Python中的类(一)
    基于session和cookie的登录验证(CBV模式)
    Django中的CBV和FBV
    python3 装饰器
    cookie和session
    基于cookie和session的登录验证
    python3 安装win32api
  • 原文地址:https://www.cnblogs.com/staginner/p/2499051.html
Copyright © 2020-2023  润新知