• 算法提高 最小方差生成树


      算法提高 最小方差生成树  
    时间限制:1.0s   内存限制:256.0MB
          
    问题描述
    给定带权无向图,求出一颗方差最小的生成树。
    输入格式
    输入多组测试数据。第一行为N,M,依次是点数和边数。接下来M行,每行三个整数U,V,W,代表连接U,V的边,和权值W。保证图连通。n=m=0标志着测试文件的结束。
    输出格式
    对于每组数据,输出最小方差,四舍五入到0.01。输出格式按照样例。
    样例输入
    4 5
    1 2 1
    2 3 2
    3 4 2
    4 1 1
    2 4 3
    4 6
    1 2 1
    2 3 2
    3 4 3
    4 1 1
    2 4 3
    1 3 3
    0 0
    样例输出
    Case 1: 0.22
    Case 2: 0.00
    数据规模与约定

    1<=U,V<=N<=50,N-1<=M<=1000,0<=W<=50。数据不超过5组。

    题目数据有问题。。。
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    double const MAX = 10000000000000.0;
    int n, m, tmp[1005], fa[55];
    double ans;
    
    struct Edge
    {
        int u, v;
        double w, val;
    }e[1005];
    
    bool cmp(Edge a, Edge b)
    {
        return a.w < b.w;
    }
    
    void UF_set(int n)
    {
        for(int i = 1; i <= n; i++)
            fa[i] = i;
    }
    
    int Find(int x)
    {
        return x == fa[x] ? x : fa[x] = Find(fa[x]);
    }
    
    void Union(int a, int b)
    {
        int r1 = Find(a);
        int r2 = Find(b);
        if(r1 != r2)
            fa[r2] = r1;
    }
    
    void Kruskal(int sum)
    {
        UF_set(n);
        int cnt = 0;
        double f_all = 0;
        double all = 0;
        double ave = sum * 1.0 / (n - 1);
        for(int i = 0; i < m; i++)
            e[i].w = (e[i].val - ave) * (e[i].val - ave);
        sort(e, e + m, cmp);
        for(int i = 0; i < m; i++)
        {
            int u = e[i].u;
            int v = e[i].v;
            if(Find(u) != Find(v))
            {
                Union(u, v);
                f_all += e[i].w;
                all += e[i].val;
                cnt ++;
            }
            if(cnt == n - 1)
                break;
        }
        if((int)all == sum)
            ans = min(ans, f_all);
    }
    
    int main()
    {
        int ca = 1;
        while(scanf("%d %d", &n, &m) != EOF && (m + n))
        {
            // if(n == 1 || n == 2)
            // {
            //     printf("0.00
    ");
            //     continue;
            // }
            int minv = 0;
            int maxv = 0;
            ans = MAX;
            for(int i = 0; i < m; i++)
            {
                scanf("%d %d %lf", &e[i].u, &e[i].v, &e[i].val);
                tmp[i] = e[i].val;
            }
            sort(tmp, tmp + m);
            for(int i = 0; i < n - 1; i++)
                minv += tmp[i];
            for(int i = m - 1; i > m - n; i--)
                maxv += tmp[i];
            for(int i = minv; i <= maxv; i++)
                Kruskal(i);
            ans = ans / (n - 1);
            printf("Case %d: %.2f
    ", ca++, ans);
        }
    }
  • 相关阅读:
    JavaBasics-15-多线程
    4.10 SpringCloud微服务技术栈
    4.3 Linux操作系统_Unix操作系统
    4.2 互联网项目架构演进
    4.1 微服务框架_引言
    4.6 Redis
    SpringBoot
    docker-dockerfile实战构建文件
    docker 安装私有仓库 registry(离线)
    基础K8S搭建(20209.08亲测成功)
  • 原文地址:https://www.cnblogs.com/asuml/p/6798307.html
Copyright © 2020-2023  润新知