http://poj.org/problem?id=2728
题目大意:求一棵生成树使得路费用和/路长之和最小(路的费用是两端点的高度差)
最小比率生成树。
我们还是01分数规划的思想将边权变为路费用-路长*枚举的答案,跑一遍最小生成树即可。
但是debug的三个小时的我要对出题人说一句。
CNM无良卡常!K算法被卡正常,堆优化Prim都被卡你是什么东西????!!!
#include<cstdio> #include<cmath> #include<cstring> #include<queue> #include<cctype> #include<algorithm> using namespace std; typedef double dl; const int N=1050; const dl INF=0x7fffffff; struct node{ dl w,h; }e[N][N]; dl dis[N],x[N],y[N],z[N]; int n; bool vis[N]; inline dl getdis(int i,int j){ dl X=x[i]-x[j],Y=y[i]-y[j]; return sqrt(X*X+Y*Y); } dl prim(dl mid){ for(int i=1;i<=n;i++)dis[i]=INF,vis[i]=0; dl ans=0;int u=1; dis[u]=0;vis[u]=1; for(int i=1;i<n;i++){ int v;dl minn=INF; for(int j=1;j<=n;j++){ if(vis[j])continue; dl w=e[u][j].h-mid*e[u][j].w; if(dis[j]>w)dis[j]=w; if(minn>dis[j]){ minn=dis[j]; v=j; } } vis[v]=1;ans+=minn;u=v; } return ans; } int main(){ while(scanf("%d",&n)!=EOF&&n){ dl l=0,r=100000; for(int i=1;i<=n;i++){ scanf("%lf%lf%lf",&x[i],&y[i],&z[i]); for(int j=1;j<i;j++){ e[i][j].w=e[j][i].w=getdis(i,j); e[i][j].h=e[j][i].h=fabs(z[i]-z[j]); } } for(int i=1;i<=50;i++){ dl mid=(l+r)/2; if(prim(mid)>=0)l=mid; else r=mid; } printf("%.3f\n",r); } return 0; }