zoukankan      html  css  js  c++  java
  • 次小生成树

    一、思路:

    先求最小生成树T,枚举添加不在T中的边,则添加后一定会形成环。

    找到环上边值第二大的边(即环中属于T中的最大边),把它删掉,计算当前生成树的权值,取所有枚举修改的生成树的最小值,即为次小生成树。

    二、代码

    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <math.h>
    #include <iostream>
    using namespace std;
    #define MAX 0x3f3f3f3f
    #define N 1010
    int n;
    double dis[N],map[N][N],Max[N][N];
    int fa[N],used[N][N],logo[N];
    struct Node
    {
        int x,y,p;
    } node[N];
    double getdistence(int x1,int y1,int x2,int y2)
    {
        double x=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
        return x;
    }
    double Prim()
    {
        double ans = 0;
        memset(logo, 0, sizeof(logo));
        memset(Max, 0, sizeof(Max));
        memset(used, 0, sizeof(used));
        logo[1] = 1;
        fa[1] = 0;
        dis[1] = 0;
        for (int i = 2; i <= n; i++)
        {
            dis[i] = map[1][i];
            fa[i] = 1;
        }
    
        for (int i = 1; i < n; i++)
        {
            double min1 = MAX;
            int now = -1;
            for (int j = 1; j <= n; j++)
            {
                if (!logo[j] && min1 > dis[j])
                {
                    min1 = dis[j];
                    now = j;
                }
            }
            if (min1 == MAX)
                return -1;
    
            ans += min1;
            logo[now] = 1;
            used[now][fa[now]] = used[fa[now]][now] = 1;
            for (int j = 1; j <= n; j++)
            {
                if (logo[j] && j != now)
                    Max[j][now] = Max[now][j] = max(Max[j][fa[now]], dis[now]);
                if (!logo[j] && dis[j] > map[now][j])
                {
                    dis[j] = map[now][j];
                    fa[j] = now;
                }
            }
        }
    
        return ans;
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            memset(map,0,sizeof(map));
            scanf("%d",&n);
            for(int i=1; i<=n; i++)
                scanf("%d %d %d",&node[i].x,&node[i].y,&node[i].p);
            for(int i=1; i<=n; i++)
                for(int j=1; j<=n; j++)
                    map[i][j]=getdistence(node[i].x,node[i].y,node[j].x,node[j].y);
            double sum=Prim();
    
            double ans=0;
            for(int i=1; i<=n; i++)
                for(int j=1; j<=n; j++)
                {
                    if(i!=j)
                    {
                        if(used[i][j])
                            ans=max(ans,(node[i].p+node[j].p)*1.0/(sum-map[i][j]));
                        else
                            ans=max(ans,(node[i].p+node[j].p)*1.0/(sum-Max[i][j]));
                    }
                }
            printf("%.2lf
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    javaweb一
    javaweb三、JDBC访问数据库
    Java学习笔记十
    socket qt基础版本
    QT+VS+添加console 解决方案
    QT创建TCP Socket通信
    左值引用与右值引用
    STL 中 map和set的区别
    C++中STL哈希表介绍
    虚函数总结
  • 原文地址:https://www.cnblogs.com/aiguona/p/7652724.html
Copyright © 2011-2022 走看看