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>
 6 #include<stack>
 7 #include<queue>
 8 #include<cmath>
 9 #include<map>
10 #include<set>
11 using namespace std;
12 typedef long long ll;
13 const int INF = 0x3f3f3f3f;
14 const int maxn=1000+5;
15 const double eps=1e-6;
16 
17 int n;
18 int x[maxn],y[maxn],z[maxn];
19 bool vis[maxn];
20 double cost[maxn][maxn],dis[maxn][maxn],d[maxn];
21 
22 
23 double prim(double x)
24 {
25     double sum=0;
26     memset(vis,0,sizeof(vis));
27     vis[1]=1; d[1]=0;
28     for(int i=2;i<=n;i++) d[i]=cost[1][i]-x*dis[1][i];
29     for(int i=2;i<=n;i++)
30     {
31         double MIN=INF;
32         int pos;
33         for(int j=1;j<=n;j++)
34         {
35             if(!vis[j] && d[j]<MIN)
36             {
37                 pos=j;
38                 MIN=d[j];
39             }
40         }
41         vis[pos]=1;
42         sum+=MIN;
43         for(int j=1;j<=n;j++)
44         {
45             if(!vis[j] && d[j]>cost[pos][j]-x*dis[pos][j])
46                 d[j]=cost[pos][j]-x*dis[pos][j];
47         }
48     }
49     return sum;
50 }
51 
52 int main()
53 {
54     //freopen("in.txt","r",stdin);
55     while(~scanf("%d",&n) && n)
56     {
57         for(int i=1;i<=n;i++)
58         {
59             scanf("%d%d%d",&x[i],&y[i],&z[i]);
60             for(int j=1;j<i;j++)
61             {
62                 cost[i][j]=cost[j][i]=abs(z[j]-z[i]);
63                 dis[i][j]=dis[j][i]=sqrt((double)(y[i]-y[j])*(y[i]-y[j])+(double)(x[i]-x[j])*(x[i]-x[j]));
64             }
65         }
66         double l=0,r=100000;
67         double ans=0;
68         while(r-l>=eps)
69         {
70             double mid=(l+r)/2.0;
71             if(prim(mid)>=0)
72             {
73                 ans=mid;
74                 l=mid;
75             }
76             else r=mid;
77         }
78         printf("%.3f
",ans);
79     }
80     return 0;
81 }
原文地址:https://www.cnblogs.com/zyb993963526/p/7403954.html