题目链接:http://poj.org/problem?id=2728
二分版 代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define sf scanf
#define pf printf
#define dpow(x) ((x) * (x))
#define esp 1e-5
#define INF 1e10
using namespace std;
const int maxn = 1000 + 5;
double A[maxn][maxn],B[maxn][maxn],D[maxn][maxn];
double x[maxn],y[maxn],h[maxn];
double dis[maxn];
bool vis[maxn];
double PRIME(int n,double l){
memset(vis,0,sizeof vis);
for(int i = 0;i < n;++i)
for(int j = 0;j < n;++j) D[i][j] = D[j][i] = A[i][j] - l * B[i][j];
for(int i = 0;i < n;++i) dis[i] = D[0][i];
dis[0] = 0;vis[0] = 1;dis[n] = INF;
int p;double tmp = 0;
for(int i = 0;i < n - 1;++i){
p = n;
for(int j = 0;j < n;++j)
if(!vis[j] && dis[j] < dis[p]) p = j;
vis[p] = 1;tmp += dis[p];
for(int j = 0;j < n;++j)
if(!vis[j] && dis[j] > D[p][j]) dis[j] = D[p][j];
}
return tmp;
}
int main(){
int n;
while( sf("%d",&n) && n ){
for(int i = 0;i < n;++i) sf("%lf %lf %lf",&x[i],&y[i],&h[i]);
for(int i = 0;i < n;++i){
for(int j = i;j < n;++j){
A[i][j] = A[j][i] = fabs(h[i] - h[j]);
B[i][j] = B[j][i] = sqrt( dpow(x[i] - x[j]) + dpow(y[i] - y[j]) );
}
}
double l = 0,r = 100,mid;
while(l + esp < r){
mid = (l + r) / 2.0;
if(PRIME(n,mid) < 0) r = mid;
else l = mid;
}
pf("%.3f\n",mid);
}
}
迭代版
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define sf scanf
#define pf printf
#define dpow(x) ((x) * (x))
#define esp 1e-5
#define INF 1e10
using namespace std;
const int maxn = 1000 + 5;
double A[maxn][maxn],B[maxn][maxn],D[maxn][maxn];
double x[maxn],y[maxn],h[maxn];
double dis[maxn];
int fa[maxn];
bool vis[maxn];
double PRIME(int n,double l){
memset(vis,0,sizeof vis);
for(int i = 0;i < n;++i)
for(int j = 0;j < n;++j) D[i][j] = D[j][i] = A[i][j] - l * B[i][j];
for(int i = 0;i < n;++i) dis[i] = D[0][i],fa[i] = 0;
vis[0] = 1;dis[n] = INF;
int p;double up = 0,low = 0;
for(int i = 0;i < n - 1;++i){
p = n;
for(int j = 0;j < n;++j)
if(!vis[j] && dis[j] < dis[p]) p = j;
vis[p] = 1;up += A[fa[p]][p],low += B[fa[p]][p];
for(int j = 0;j < n;++j)
if(!vis[j] && dis[j] > D[p][j]) dis[j] = D[p][j],fa[j] = p;
}
return up / low;
}
int main(){
int n;
while( sf("%d",&n) && n ){
for(int i = 0;i < n;++i) sf("%lf %lf %lf",&x[i],&y[i],&h[i]);
for(int i = 0;i < n;++i){
for(int j = i;j < n;++j){
A[i][j] = A[j][i] = fabs(h[i] - h[j]);
B[i][j] = B[j][i] = sqrt( dpow(x[i] - x[j]) + dpow(y[i] - y[j]) );
}
}
double ans = 0,tmp = 10;
while(fabs(ans - tmp) > esp){
ans = tmp;
tmp = PRIME(n,tmp);
}
pf("%.3f\n",ans);
}
}