题意要求a/b的最大值。 其中a是任意两点的点权和,b是除去这两点剩下的最小生成树的值。

我们可以先求出最小生成树,然后不断删边,然后求出删去这条边后的剩下的点的最小生成树的值(联想到次小生成树)。

删边的过程可以用dfs枚举。

代码如下啊:

#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
const int N = 1005;
int INF = 99999999;

int connect[N][N],  data[N][3], Dres[5];
int n, m;
double map[N][N], maxx[N][N] ,res = -INF, tempb;

void init()
{
    fill(connect[0], connect[0] + N * N, 0);
    fill(maxx[0], maxx[0] + N * N, 0);
    fill(map[0], map[0] + N * N, 0);
    res = -INF;
};

double getDis(double x1, double y1, double x2, double y2)
{
    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
};
double prim()
{
    int mark[N], father[N];
    double dis[N], sum = 0;

    fill(mark, mark + N, 0);

    for (int i = 1; i <= n; i++)
    {
        dis[i] = map[1][i];
        father[i] = 1;
    }
    dis[1] = 0, mark[1] = 1 ;

    for (int i = 2; i <= n; i++)
    {
        double min1 = INF;
        
        int u = -1;

        for (int j = 1; j <= n; j++)if(mark[j] == 0 && min1 > dis[j])
        {
            u = j;
            min1 = dis[j];
        }
        sum += min1;
        mark[u] = 1;
        connect[u][father[u]] = connect[father[u]][u] = 2;
        maxx[u][father[u]] = maxx[father[u]][u] = min1;

        for (int j = 1; j <= n; j++)
        {
            if(j != u && mark[j] == 1)
            {
                maxx[j][u] = maxx[u][j] = max(maxx[j][father[u]], dis[u]);
            }
            if(mark[j] == 0 && dis[j] > map[u][j])
            {
                dis[j] = map[u][j];
                father[j] = u;
            }
        }
    }

    return sum;
};

void dfs(int index, int len, double a)
{
    if(index  == 3)
    {
        double b = tempb - maxx[Dres[1]][Dres[2]];
        double ab = a / b;
    //    printf("%d %d\n", Dres[1], Dres[2]);
        if(res < ab)
        {
            res = ab;
        }
        return;
    }
    else
    {
        for (int i = len; i <= n; i++)
        {
            Dres[index] = i ;
            dfs(index + 1, i + 1,a + data[i][2]);
        }
        return;
    }
    

};


/*
2
4
1 1 20
1 2 30
200 2 80
200 1 100
3
1 1 20
1 2 30
2 2 40
Sample Output
65.00
70.00
*/
int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        
        scanf("%d", &n);
        init();
        for (int i = 1; i <= n; i++)
        {
            scanf("%d %d %d", &data[i][0], &data[i][1], &data[i][2]);
        }

        for (int i = 1; i <= n; i++)
        {
            for (int j = i + 1; j <= n; j++)
            {
                connect[i][j] = connect[j][i] = 1;
                map[i][j] = map[j][i] = getDis(data[i][0], data[i][1], data[j][0], data[j][1]);
            }
        }

 
        tempb = prim();
        dfs(1, 1, 0);
        printf("%0.2lf\n", res);

     }
    



    return  0;
}