最优比例生成树模板

/*
    01最优(小)比例生成树
    求最大比例更改prim即可
    poj2728 将图中点连成一棵树满足 总花费/总长度 最小
*/


int n,m;
double d[1005],cost[1005],ben[1005];
double pic[1005][1005];  ///两点间距离
double cpic[1005][1005]; ///两点间花费
int vis[1005];
int pre[1005];           ///记录父节点
struct Node{
    int x,y,h;
    double ans;
}node[1111];
double prim(double mid){ ///用prim思想
    mst(vis,0);
    mst(pre,0);
    double c=0,b=0;
    for(int i=0;i<n;++i)d[i]=cpic[0][i]-pic[0][i]*mid;
    for(int i=1;i<n;++i){
        double m=inf;int u=-1;
        for(int j=1;j<n;++j)
            if(!vis[j]&&d[j]<m)
                m=d[u=j];
        if(u==-1)break;
        vis[u]=1;
        c+=cpic[u][pre[u]];
        b+=pic[u][pre[u]];
        for(int j=1;j<n;++j)
            if(!vis[j]&&d[j]>cpic[u][j]-pic[u][j]*mid){
                ///cpic[u][j]-pic[u][j]*mid仍然是分数转换思想
                ///更新最优(小)比例
                d[j]=cpic[u][j]-pic[u][j]*mid;
                pre[j]=u;
            }
    }
    return c/b;
}
double dis(int x,int y){  ///求两点间距离
    double x1=node[x].x-node[y].x;
    double y1=node[x].y-node[y].y;
    double len=sqrt(x1*x1+y1*y1);
    return len;
}
int main(){
    int i,j,group,temp;
    while(scanf("%d",&n)!=EOF&&n){
        for(i=0;i<n;++i)scanf("%d%d%d",&node[i].x,&node[i].y,&node[i].h);
        for(i=0;i<n;++i)for(j=i+1;j<n;++j)if(i!=j){
            pic[i][j]=pic[j][i]=dis(i,j);
            cpic[i][j]=cpic[j][i]=fabs(node[i].h-node[j].h);
        }
        double ans;
        double temp=0;
        do{
            ans=temp;
            temp=prim(ans);
        }while(fabs(ans-temp)>1e-4);
        printf("%.3f\n",ans);
    }
    return 0;
}

 

posted @ 2016-08-04 22:23  Kurokey  阅读(273)  评论(0编辑  收藏  举报