题意:最有比例生成树
最近做了好几道这样的二分答案求解的题,
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
const int N = 1009;
const int INF = 0x3f3f3f3f;
double map[N][N];
int re[N][3];
double dis[N][N],mdis[N];
bool visit[N];
int high[N][N];
int n;
double setdis(int i,int j)
{
return sqrt(1.0*(re[i][0]-re[j][0])*(re[i][0]-re[j][0])+(re[i][1]-re[j][1])*(re[i][1]-re[j][1]));
}
void init()
{
for(int i=0;i<n;i++)
{
scanf("%d%d%d",&re[i][0],&re[i][1],&re[i][2]);
for(int j=0;j<i;j++)
dis[i][j] = dis[j][i] = setdis(i,j),
high[i][j] = high[j][i] = abs(re[i][2]-re[j][2]);
}
}
bool oor(double m)
{
memset(visit,false,sizeof(visit));
for(int i=0;i<n;i++)
for(int j=0;j<i;j++)
map[i][j] = map[j][i] = high[i][j]-dis[i][j]*m;
double ans=0;
for(int i=1;i<n;i++)
mdis[i] = map[0][i];
mdis[0]=0;visit[0] = true;
while(1)
{
double mindis = 1e12;
int minone = -1;
for(int i=0;i<n;i++)
if(!visit[i]&&mdis[i]<mindis)
mindis = mdis[i],minone =i;
if(minone==-1)
return ans<=0;
ans+=mindis;
visit[minone] = true;
for(int i=1;i<n;i++)
if(!visit[i]&&mdis[i]>map[minone][i])
mdis[i] = map[minone][i];
}
}
void solve()
{
double r = 1e12,l = 0,mid;
while((r-l)>0.00001)
{
mid = (l+r)/2;
if(oor(mid))
r = mid;
else
l = mid;
}
printf("%.3lf\n",mid);
}
int main()
{
freopen("in.txt","r",stdin);
while(~scanf("%d",&n)&&n)
{
init();
solve();
}
return 0;
}