Desert King(POJ2728+最优比率生成树+二分)
题目链接:http://poj.org/problem?id=2728
题目:
题意:求一颗生成树,使得费用与距离的比值最小,其中距离等于两点之间的平面欧拉距离,费用为z坐标之差。
思路:
由上图我们可以得知,我们只需对x进行二分(最大化平均值),以cost[i]-len[i]*x为边权跑prime即可。
代码实现如下:
1 #include <set> 2 #include <map> 3 #include <queue> 4 #include <stack> 5 #include <cmath> 6 #include <bitset> 7 #include <cstdio> 8 #include <string> 9 #include <vector> 10 #include <cstdlib> 11 #include <cstring> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 16 typedef long long ll; 17 typedef pair<ll, ll> pll; 18 typedef pair<ll, int> pli; 19 typedef pair<int, ll> pil;; 20 typedef pair<int, int> pii; 21 typedef unsigned long long ull; 22 23 #define lson i<<1 24 #define rson i<<1|1 25 #define bug printf("*********\n"); 26 #define FIN freopen("D://code//in.txt", "r", stdin); 27 #define debug(x) cout<<"["<<x<<"]" <<endl; 28 #define IO ios::sync_with_stdio(false),cin.tie(0); 29 30 const double eps = 1e-8; 31 const int mod = 10007; 32 const int maxn = 1000 + 7; 33 const double pi = acos(-1); 34 const int inf = 0x3f3f3f3f; 35 const ll INF = 0x3f3f3f3f3f3f3f; 36 37 int n, x, y, z; 38 double ans; 39 int vis[maxn]; 40 double mp[maxn][maxn], dis[maxn]; 41 42 struct node { 43 int x, y ,z; 44 }p[maxn]; 45 46 double dist(node& a, node& b) { 47 return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); 48 } 49 50 bool prime(double x) { 51 for(int i = 1; i <= n; i++) { 52 dis[i] = inf; 53 vis[i] = 0; 54 } 55 ans = 0; 56 dis[1] = 0; 57 for(int i = 1; ; i++) { 58 double mx = inf; 59 int t = -1; 60 for(int j = 1; j <= n; j++) { 61 if(!vis[j] & mx > dis[j]) { 62 mx = dis[j]; 63 t = j; 64 } 65 } 66 if(t == -1) break; 67 ans += mx; 68 vis[t] = 1; 69 for(int j = 1; j <= n; j++) { 70 if(!vis[j] && dis[j] > fabs(p[t].z - p[j].z) - mp[t][j] * x) { 71 dis[j] = fabs(p[t].z - p[j].z) - mp[t][j] * x; 72 } 73 } 74 } 75 return ans >= 0; 76 } 77 78 int main() { 79 //FIN; 80 while(~scanf("%d", &n) && n) { 81 for(int i = 1; i <= n; i++) { 82 scanf("%d%d%d", &p[i].x, &p[i].y, &p[i].z); 83 } 84 for(int i = 1; i <= n; i++) { 85 for(int j = 1; j <= n; j++) { 86 mp[i][j] = dist(p[i], p[j]); 87 } 88 } 89 double ub = 100, lb = 0, mid; 90 while(ub - lb > eps) { 91 mid = (ub + lb) / 2; 92 if(prime(mid)) lb = mid; 93 else ub = mid; 94 } 95 printf("%.3f\n", lb); 96 } 97 return 0; 98 }
版权声明:本文允许转载,转载时请注明原博客链接,谢谢~