题目意思是给你一个完全图,每个点有一个权值。
求一棵生成树。你可以使其中一条边权值变成0.使得该边两点的权值和除以生成树的边权和最大。
思路:
#include <set>
#include <map>
#include <queue>
#include <deque>
#include <cmath>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <iostream>
#include <algorithm>
using namespace std;
#define L(i) i<<1
#define R(i) i<<1|1
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-9
#define maxn 1000010
#define MOD 1000000007
#define zero(x) (((x)>0?(x):-(x))<eps)
int n,last,nearvex[1010],k,fa[1010];
double lowcost[1010],edge[1010][1010];
double ans,weight;
int a[1010];
vector<int> son[10010];
struct node
{
int x,y,num;
}cnt[1010];
double get_dis(int x,int y)
{
return sqrt((cnt[x].x-cnt[y].x)*(cnt[x].x-cnt[y].x)+(cnt[x].y-cnt[y].y)*(cnt[x].y-cnt[y].y));
}
void prim(int u)
{
k = 0;
weight = 0;
nearvex[u] = -1;
a[k++] = u;
for(int i = 0; i <= n; i++)
son[i].clear();
for(int i = 2; i <= n; i++)
{
lowcost[i] = edge[u][i];
nearvex[i] = u;
fa[i] = u;
}
for(int i = 1; i <= n; i++)
{
int v = -1;
double Min = INF;
for(int j = 1; j <= n; j++)
if(nearvex[j] != -1 && lowcost[j] < Min)
{
Min = lowcost[j];
v = j;
last = j;
}
if(v != -1)
{
son[nearvex[v]].push_back(v);
nearvex[v] = -1;
a[k++] = v;
weight += Min;
for(int j = 1; j <= n; j++)
if(nearvex[j] != -1 && edge[v][j] < lowcost[j])
{
lowcost[j] = edge[v][j];
nearvex[j] = v;
fa[j] = v;
}
}
}
}
void dfs1(int fa,int en,int& Max)
{
if(!son[fa].size())
{
Max = max(Max,cnt[fa].num);
return;
}
for(int i = 0; i < son[fa].size(); i++)
{
if(son[fa][i] == en)
continue;
//printf("%d %d\n",fa,son[fa][i]);
Max = max(Max,cnt[son[fa][i]].num);
dfs1(son[fa][i],en,Max);
}
}
void dfs2(int fa,int &Max)
{
if(!son[fa].size())
{
Max = max(Max,cnt[fa].num);
return;
}
for(int i = 0; i < son[fa].size(); i++)
{
Max = max(Max,cnt[son[fa][i]].num);
//printf("%d %d\n",fa,son[fa][i]);
dfs2(son[fa][i],Max);
}
}
void solve(int x)
{
int m1 = -INF,m2 = -INF;
dfs1(1,a[x],m1);
dfs2(a[x],m2);
//printf("%d %d\n",m1,m2);
//printf("%f %f\n",weight,edge[a[x]][fa[a[x]]]);
//printf("%d %d\n\n",a[x],fa[a[x]]);
double t = (m1+m2)/(weight-edge[a[x]][fa[a[x]]]);
ans = max(ans,t);
}
int main()
{
int t,C = 1;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i = 1; i <= n; i++)
scanf("%d%d%d",&cnt[i].x,&cnt[i].y,&cnt[i].num);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
edge[i][j] = get_dis(i,j);
prim(1);
ans = 0;
//for(int i = 0 ; i < n; i++)
// printf("%d\n",a[i]);
for(int i = 1; i < n; i++)
solve(i);
printf("%.2f\n",ans);
}
return 0;
}