最优比例生成树模板

/*
    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;
}
时间: 2024-08-09 19:51:41

最优比例生成树模板的相关文章

poj 2718 最优比例生成树(01分数规划)模板

/* 迭代法 :204Ms */ #include<stdio.h> #include<string.h> #include<math.h> #define N 1100 #define eps 1e-10 #define inf 0x3fffffff struct node { int u,v,w; }p[N]; double ma[N][N]; double distance(int i,int j) { return sqrt(1.0*(p[i].u-p[j].u

ZOJ 2728 Desert King(最优比例生成树)

Desert King Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 20586   Accepted: 5777 Description David the Great has just become the king of a desert country. To win the respect of his people, he decided to build channels all over his coun

poj 2728(Desert King) 最优比例生成树 (分数规划)

这题是最小生成树的一种扩展,就是求一棵树  使得 k =sigma(cost)/ sigma(len)  最小.   其中cost 为每条边花费,len为长度.  这实际上就是一个最优比例生成树.最优比例生成树的求解使用了分数规划的方法.  我们先任取k,假设k是最小值,那么sigma(ccost)-k*sigma(len)==0  .那么我们就新建图边权 为  ccosti-k*leni  .求一次最小生成树,如果生成树权值小于0,那么书名其实k还是有减小的空间的,否则,k不可能是最小.这样我

POJ 2728 Desert King 最优比例生成树

最优比例生成树,迭代方法..... Desert King Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 21086   Accepted: 5916 Description David the Great has just become the king of a desert country. To win the respect of his people, he decided to build channels

poj2728 Desert King,最优比例生成树

题意:有n个村庄,村庄在不同坐标和海拔,现在要对所有村庄供水,只要两个村庄之间有一条路即可, 建造水管距离为坐标之间的欧几里德距离(好象是叫欧几里德距离吧),费用为海拔之差 现在要求方案使得费用与距离的比值最小 很显然,这个题目是要求一棵最优比率生成树, 0-1分数规划,0-1分数规划是分数规划的一种特殊情况,分数规划适用于求解最优化问题的,对于求最大的对应解,该理论也有效 这是从网上找到的具体的最优比率生成树的方法的讲解 //////////////////// 概念 有带权图G, 对于图中每

poj 2728 Desert King 参数搜索解最优比例生成树

题意: 图中每条边有两个权值(cost,len),求其一棵生成树,使sum(cost)/sum(len)最小. 分析: 转化为求边权为s0*len-cost的最大生成树+牛顿迭代.s0为具有单调性迭代系数. 代码: //poj 2728 //sep9 #include <iostream> #include <cmath> #include <vector> using namespace std; const int maxN=1024; struct P { int

01分数规划poj2728(最优比例生成树)

Desert King Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 21766   Accepted: 6087 Description David the Great has just become the king of a desert country. To win the respect of his people, he decided to build channels all over his coun

(最优比例生成树) poj 2728

Desert King Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 21855   Accepted: 6103 Description David the Great has just become the king of a desert country. To win the respect of his people, he decided to build channels all over his coun

【POJ2728】Desert King 最优比率生成树

题目大意:给定一个 N 个点的无向完全图,边有两个不同性质的边权,求该无向图的一棵最优比例生成树,使得性质为 A 的边权和比性质为 B 的边权和最小. 题解:要求的答案可以看成是 0-1 分数规划问题,即:选定一个数 mid,每次重新构建边权为 \(a[i]-mid*b[i]\) 的图,再在图上跑一遍最小生成树(这里由于是完全图,应该采用 Prim 算法)判断最小值和给定判定的最小值的关系即可,这里为:若最小值大于 mid,则下界提高,否则上界下降. 代码如下 #include<cmath>