POJ-2728-01分数规划,Dinkelbach迭代

来源:互联网 发布:python脚本写文件 编辑:程序博客网 时间:2024/06/03 22:56

题目大意:最优比例生成树,分子为两点间的垂直距离,分母为欧几米德距离;

题目解析:用迭代+prim,更新dist,dist为abs(ax-b.x)-ans*dist(a,b);(题目输出只能用f不能用lf)

AC代码:

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<cmath>using namespace std;const int maxn=1010;struct node{    int x,y,z;}q[maxn];double  dis(node a,node b){    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}int n;double dist[maxn];bool vis[maxn];int pre[maxn];double prime(double x){    memset(vis,0,sizeof(vis));    for(int i=2;i<=n;i++)    {        dist[i]=abs(q[i].z-q[1].z)-x*dis(q[i],q[1]);        pre[i]=1;    }    vis[1]=1;    dist[1]=0;    pre[1]=1;    double cost=0,length=0;    for(int i=1;i<n;i++)    {        double mi=100000000;        int u=-1;        for(int j=1;j<=n;j++)        {            if(vis[j])  continue;            if(mi>dist[j])            {                u=j;                mi=dist[j];            }        }        vis[u]=1;        cost+=abs(q[pre[u]].z-q[u].z);        length+=dis(q[pre[u]],q[u]);        for(int j=1;j<=n;j++)        {            double temp=abs(q[u].z-q[j].z)-x*dis(q[j],q[u]);            if(!vis[j]&&temp<dist[j])            {                dist[j]=temp;                pre[j]=u;            }        }    }    return cost/length;}int main(){    while(scanf("%d",&n)!=EOF&&n)    {        for(int i=1;i<=n;i++)        {            scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].z);        }        double a=0,b;        while(1)        {            b=prime(a);            if(abs(a-b)<1e-4)  break;            a=b;        }        printf("%.3f\n",a);    }    return 0;}


0 0