Poj 2728 DK
最优比率生成树,参数搜索。建议去这里http://wenku.baidu.com/view/87ecda38376baf1ffc4fad25.html看看。
我写的二分比较奇葩,精度调起来比较疼,弄到1e-6就ok了。
View Code
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring> 6 #define maxn 1024 7 #define inf 2147483646 8 using namespace std; 9 10 int x[maxn],y[maxn],h[maxn]; 11 double d[maxn][maxn],c[maxn][maxn],val[maxn][maxn],low[maxn]; 12 bool v[maxn]; 13 int n,m; 14 double prim(double p) 15 { 16 double sum=0; 17 for (int i=0;i<n;i++) 18 for (int j=0;j<n;j++) 19 if (i!=j) 20 val[i][j]=c[i][j]-p*d[i][j]; 21 for (int i=1;i<n;i++) low[i]=val[0][i]; 22 memset(v,0,sizeof(v)); 23 for (int i=1;i<=n-1;i++) 24 { 25 double m=inf; int k=0; 26 for (int j=1;j<n;j++) 27 if (low[j]<m&&!v[j]) m=low[j],k=j; 28 v[k]=1; 29 sum+=m; 30 for (int j=1;j<n;j++) 31 if (val[k][j]<low[j]&&!v[j]) low[j]=val[k][j]; 32 } 33 return sum; 34 } 35 36 double dis(int i,int j) 37 { 38 return sqrt((double)(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])); 39 } 40 41 int main() 42 { 43 //freopen("dk.in","r",stdin); 44 scanf("%d",&n); 45 while (n!=0) 46 { 47 for (int i=0;i<n;i++) 48 scanf("%d %d %d",&x[i],&y[i],&h[i]); 49 double mind=inf,maxd=0,minc=inf,maxc=0; 50 for (int i=0;i<n;i++) 51 for (int j=0;j<n;j++) 52 if (i!=j) 53 { 54 d[i][j]=dis(i,j); 55 mind=min(d[i][j],mind); 56 maxd=max(d[i][j],maxd); 57 c[i][j]=fabs((double)h[i]-h[j]); 58 minc=min(c[i][j],minc); 59 maxc=max(c[i][j],maxc); 60 } 61 double l=minc/maxd,r=maxc/mind,ans=0; 62 while (l-r<=1e-6) 63 { 64 double mid=(l+r)/2.0; 65 if (prim(mid)<=0.0) r=mid-0.000001,ans=mid;//所有>0的解均不合法 66 else l=mid+0.000001; 67 } 68 printf("%.3lf\n",ans); 69 scanf("%d",&n); 70 } 71 return 0; 72 } 73 74
AC without art, no better than WA !