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)*(p[i].u-p[j].u)+1.0*(p[i].v-p[j].v)*(p[i].v-p[j].v));
}
int n;
double prime(int u,double r) {
  int i,j,vis[N],pre[N];
  double dis[N],len=0,cost=0,total=0;
  for(i=1;i<=n;i++)  {
      dis[i]=fabs(1.0*p[u].w-1.0*p[i].w)-ma[u][i]*r;
      pre[i]=u;
  }
  memset(vis,0,sizeof(vis));
  vis[1]=1;
  for(i=1;i<n;i++) {
    double  minn=inf;
    int index=-1;
    for(j=1;j<=n;j++)
        if(!vis[j]&&minn>dis[j]) {
            minn=dis[j];
            index=j;
        }
    if(index!=-1) {
        vis[index]=1;
        len+=ma[pre[index]][index];
        cost=cost+fabs(1.0*p[pre[index]].w-1.0*p[index].w);
        //total+=dis[index];
        for(j=1;j<=n;j++) {
            double f=fabs(1.0*p[index].w-1.0*p[j].w)-ma[index][j]*r;
            if(!vis[j]&&f<dis[j]) {
                dis[j]=f;
                pre[j]=index;
            }
        }
    }
  }
 // return total;
 return cost/len;
}
int main() {
    int i,j;
    while(scanf("%d",&n),n) {
        for(i=1;i<=n;i++)
            scanf("%d%d%d",&p[i].u,&p[i].v,&p[i].w);
        for(i=1;i<=n-1;i++)
            for(j=i+1;j<=n;j++)
            ma[i][j]=ma[j][i]=distance(i,j);
          /*  double l=0.0,r=100.0;
            while(r-l>eps) {
                double mid=(l+r)/2;
                if(prime(1,mid)>=0)l=mid;
                else  r=mid;
            }*/
            double a=0,b;
            while(1) {
                b=prime(1,a);
                if(fabs(a-b)<eps)break;
                a=b;
            }
        //printf("%.3f\n",r);
        printf("%.3f\n",b);
    }
return 0;
}
/*
二分法:1766ms
*/
#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)*(p[i].u-p[j].u)+1.0*(p[i].v-p[j].v)*(p[i].v-p[j].v));
}
int n;
double prime(int u,double r) {
  int i,j,vis[N],pre[N];
  double dis[N],len=0,cost=0,total=0;
  for(i=1;i<=n;i++)  {
      dis[i]=fabs(1.0*p[u].w-1.0*p[i].w)-ma[u][i]*r;
      pre[i]=u;
  }
  memset(vis,0,sizeof(vis));
  vis[1]=1;
  for(i=1;i<n;i++) {
    double  minn=inf;
    int index=-1;
    for(j=1;j<=n;j++)
        if(!vis[j]&&minn>dis[j]) {
            minn=dis[j];
            index=j;
        }
    if(index!=-1) {
        vis[index]=1;
       // len+=ma[pre[index]][index];
        //cost=cost+fabs(1.0*p[pre[index]].w-1.0*p[index].w);
        total+=dis[index];
        for(j=1;j<=n;j++) {
            double f=fabs(1.0*p[index].w-1.0*p[j].w)-ma[index][j]*r;
            if(!vis[j]&&f<dis[j]) {
                dis[j]=f;
                pre[j]=index;
            }
        }
    }
  }
  return total;
// return cost/len;
}
int main() {
    int i,j;
    while(scanf("%d",&n),n) {
        for(i=1;i<=n;i++)
            scanf("%d%d%d",&p[i].u,&p[i].v,&p[i].w);
        for(i=1;i<=n-1;i++)
            for(j=i+1;j<=n;j++)
            ma[i][j]=ma[j][i]=distance(i,j);
            double l=0.0,r=100.0;
            while(r-l>eps) {
                double mid=(l+r)/2;
                if(prime(1,mid)>=0)l=mid;
                else  r=mid;
            }
            /*double a=0,b;
            while(1) {
                b=prime(1,a);
                if(fabs(a-b)<eps)break;
                a=b;
            }*/
        printf("%.3f\n",r);
        //printf("%.3f\n",b);
    }
return 0;
}

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

时间: 2024-11-03 16:27:25

poj 2718 最优比例生成树(01分数规划)模板的相关文章

Desert King (poj 2728 最优比率生成树 0-1分数规划)

Language: Default Desert King Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 22113   Accepted: 6187 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

POJ 2728 Desert King (最优比率生成树---01分数规划)

题目地址:POJ 2728 01分数规划的应用之一-最优比率生成树. 跟普通的01分数规划类似,只是这题的验证函数改成了最小生成树来验证.弱用的迭代法. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map>

POJ 2728 Desert King(最优比率生成树 01分数规划)

http://poj.org/problem?id=2728 题意: 在这么一个图中求一棵生成树,这棵树的单位长度的花费最小是多少? 思路: 最优比率生成树,也就是01分数规划,二分答案即可,题目很简单,因为这题是稠密图,所以用prim算法会好点. 1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<vector>

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不可能是最小.这样我

POJ2728 最小比率生成树/0-1分数规划/二分/迭代(迭代不会)

用01分数规划 + prime + 二分 竟然2950MS惊险的过了QAQ 前提是在TLE了好几次下过的 = = 题目意思:有n个村庄,村庄在不同坐标和海拔,现在要对所有村庄供水,只要两个村庄之间有一条路即可,建造水管距离为坐标之间的欧几里德距离,费用为海拔之差,现在要求方案使得费用与距离的比值最小,很显然,这个题目是要求一棵最优比率生成树. 解题思路: 对答案进行二分,当把代进去的答案拿来算最小生成树的时候,一旦总路径长度为0,就是需要的答案. 0-1规划是啥? 概念有带权图G, 对于图中每条

01分数规划模板

/* 01分数规划模板(Dinkelbach) 01分数规划就是把 sum(a)/sum(b)转换成 f(x)=sum(a)-ans*sum(b); 当f(x)取到0时,ans取到了最大(小)值 poj 2976 两个长度为n的数组a,b 可以除去m个,怎样选择才能使剩下的 sum(a)/sum(b)的百分数最大 */ int n,m; struct Node{ int a,b; double v; ///用于排序筛选较大的值(题目要求极大值 bool operator<(const Node&am

POJ 3621 Sightseeing Cows 最大密度环 01分数规划

最大密度环 01分数规划 首先的一个结论就是,不会存在环套环的问题,即最优的方案一定是一个单独的环,而不是大环套着小环的形式.这个的证明其实非常的简单,大家可以自己想一下(提示,将大环上的收益和记为x1,花费为y1,小环上的为x2,y2.重叠部分的花费为S.表示出来分类讨论即可).有了这个结论,我们就可以将花费和收益都转移到边上来了,因为答案最终一定是一个环,所以我们将每一条边的收益规定为其终点的收益,这样一个环上所有的花费和收益都能够被正确的统计. 解决了蛋疼的问题之后,就是01分数规划的部分

『POJ 2976』Dropping tests (01分数规划)

题目链接 Descrip In a certain course, you take n tests. If you get ai out of bi questions correct on test i, your cumulative average is defined to be . Given your test scores and a positive integer k, determine how high you can make your cumulative avera

poj 3621 Sightseeing Cows(最优比例生成环,01分数规划)

http://poj.org/problem?id=3621 大致题意:给出一个有向图,每个点都有一个点权,每条有向边也都有一个边权,要求出一个环使得环中点权之和与边权之和的比值最大. 思路:和最优比率生成树异曲同工.设点权是v[i],边权是e[i].不同的是这里一个是点,一个是边.怎么像生成树一样把这两个值放到一起呢?可以把他们都转化到边上.同样的二分λ,每次给边重新赋权为v[i] - λ*e[i](v[i]是该边终点的点权).因为要求比值最大,那么在这前提下于图中的所有环都<=0, 所以我们