POJ2728 Desert King 最优比率生成树

/*这道题不使用堆排序,直接枚举所有边权求最小边权要更快,可以节省100ms,原因是每一次堆排中,堆的初始数据都发生了变化,需要反复的建堆,如果是对少量边排序,应该是kruskal+堆排序要快*/

 #include <iostream>
#include <cmath>
#include <cstdio>
using namespace std;

const long M=10000000;
double dist[1001][1001],cost[1001][1001],rate[1001];
int used[1001],pre[1001],a[1001];
long n,m;
double prim(double r);
int sort();
void heap(int i);

int main()
{
 double ra,rn,tmp;
 long i,j;
 long x[1001],y[1001],h[1001];
 while (cin>>n&&n)
 {
  for (i=1;i<=n;i++)
  cin>>x[i]>>y[i]>>h[i];
  for (i=1;i<=n;i++)
  for (j=i+1;j<=n;j++)
  {
  tmp=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
  dist[i][j]=dist[j][i]=sqrt(tmp);
  cost[i][j]=cost[j][i]=labs(h[i]-h[j]);
  }
  for (ra=0,rn=1;fabs(rn-ra)>=0.0001;ra=prim(ra))
  rn=ra; 
  printf("%.3lf/n",rn);
 }
 return 0;
}

int sort()
{
 int i;
 for(m=0,i=1;i<=n;i++)
  if (!used[i])
  a[++m]=i;
 for (i=m/2;i>=1;i--)
  heap(i);
 return a[1];
}

void heap(int i)
{
 int j;
 int tmp=a[i];
 j=2*i;
 while (j<=m)
 {
  if (j<m&&rate[a[j]]>rate[a[j+1]])
  j++;
  if (rate[tmp]>rate[a[j]])
  {
  a[i]=a[j];
  i=j;
  j=2*i;
  }
  else
  break;
 }
 a[i]=tmp;
}

double prim(double r)
{
 int i,k,t;
 double sumd,sumc;
 for (i=0;i<=n;i++)
 {
  rate[i]=M;
  pre[i]=1;
  used[i]=0;
 }
 rate[1]=0;
 sumd=sumc=0;
 for (k=1;k<=n;k++)
 {
  t=sort();
  used[t]=1;
  sumd+=dist[t][pre[t]];
  sumc+=cost[t][pre[t]];
  for (i=1;i<=n;i++)
  if (!used[i]&&cost[t][i]-r*dist[t][i]<rate[i])
  {
  pre[i]=t;
  rate[i]=cost[t][i]-r*dist[t][i];
  }
 }
 return sumc/sumd;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值