思路: 我们只需要n方 处理出u到v的最小生成树上的最大路径 记录在cost 数组中。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef pair<int ,int > pii;
const int N=1e3+5;
const int M=1e6+5;
double cost[N][N];
struct node
{
double w;
int u,v;
}edges[M];
bool cmp(node a,node b)
{
return a.w<b.w;
}
int tx[N],ty[N];
int peo[N];
int f[N];
int n;
double get_dis(int i,int j)
{
int ax,bx,ay,by;
ax=tx[i]; bx=tx[j];
ay=ty[i]; by=ty[j];
ax=abs(ax-bx); ay=abs(ay-by);
return sqrt(ax*ax+ay*ay);
}
int getf(int x)
{
return f[x]==x?x:(f[x]=getf(f[x]));
}
int merge(int x,int y)
{
int t1=getf(x);
int t2=getf(y);
if(t1!=t2){
f[t2]=t1;
return 1;
}
return 0;
}
int head[N];
int totc;
int vis[N];
struct node1
{
int to;
double w;
int next;
}Edge[2*N+5];
void add(int u,int v,double w)
{
Edge[++totc].to=v; Edge[totc].w=w; Edge[totc].next=head[u]; head[u]=totc;
}
int Fa;
void dfs(int u,int fa,double maxx)
{
cost[Fa][u]=maxx;
for(int i=head[u];i!=-1;i=Edge[i].next)
{
int v=Edge[i].to;
double w=Edge[i].w;
if(v==fa) continue;
dfs(v,u,max(maxx,w));
}
return ;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d %d %d",&tx[i],&ty[i],&peo[i]);
}
int tot=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j) continue;
edges[++tot].u=i; edges[tot].v=j; edges[tot].w=get_dis(i,j);
}
}
totc=0;
memset(head,-1,sizeof(head));
sort(edges+1,edges+tot+1,cmp);
int cnt=1;
for(int i=0;i<=n;i++) f[i]=i;
int u,v;
double sum=0;
for(int i=1;i<=tot;i++){
u=edges[i].u; v=edges[i].v;
if(merge(u,v)){
sum+=edges[i].w;
cnt++;
add(u,v,edges[i].w);
add(v,u,edges[i].w);
if(cnt==n) break;
}
}
//cout<<"sum "<<sum<<endl;
for(int i=1;i<=n;i++){
Fa=i;
dfs(i,-1,0);
}
double A,B;
double ans=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++){
if(i==j) continue;
A=(peo[i]+peo[j])*1.0;
B=sum-cost[i][j];
//if(B==0) continue;
ans=max(ans,A/B);
}
}
printf("%.2f\n",ans);
}
return 0;
}