Poj--2728(prim,最优比率生成树)
2014-11-21 11:49:14
思路:01分数规划的题,用二分需要好的姿势才不会T....(不会迭代- -,待会学)
由于是稠密图,用prim高效,而且每个点对间都有边,所以就不用傻X地去O(n^2)建边了- -,直接扫描全部点。
思路就是二分答案的上下界,然后把边权转化成d[i] = cost[i] - L * dis[i]去求prim即可。eps精度卡到1e-6 (智商下线把prim打错了- -)
1 /************************************************************************* 2 > File Name: 2728.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Fri 21 Nov 2014 12:16:22 AM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <map> 14 #include <set> 15 #include <stack> 16 #include <queue> 17 #include <iostream> 18 #include <algorithm> 19 using namespace std; 20 #define lp (p << 1) 21 #define rp (p << 1|1) 22 #define getmid(l,r) (l + (r - l) / 2) 23 #define MP(a,b) make_pair(a,b) 24 typedef long long ll; 25 const int INF = 1 << 30; 26 const int maxn = 1010; 27 const double eps = 1e-6; 28 29 int N; 30 double x[maxn],y[maxn],z[maxn],cost[maxn][maxn],dis[maxn][maxn]; 31 double mincost[maxn]; 32 int vis[maxn]; 33 34 bool Prim(double val){ 35 memset(vis,0,sizeof(vis)); 36 fill(mincost + 2,mincost + N + 1,(double)INF); 37 mincost[1] = 0.0; 38 double res = 0.0; 39 int p; 40 for(int k = 1; k <= N; ++k){ 41 double tmin = (double)INF; 42 for(int i = 1; i <= N; ++i) if(!vis[i] && mincost[i] < tmin){ 43 tmin = mincost[p = i]; 44 } 45 vis[p] = 1; 46 res += tmin; 47 for(int i = 1; i <= N; ++i) if(!vis[i]){ 48 double tmp = cost[p][i] - val * dis[p][i]; 49 if(mincost[i] > tmp){ 50 mincost[i] = tmp; 51 } 52 } 53 54 } 55 if(res < eps) return true; 56 return false; 57 } 58 59 int main(){ 60 while(scanf("%d",&N) != EOF && N){ 61 for(int i = 1; i <= N; ++i){ 62 scanf("%lf%lf%lf",&x[i],&y[i],&z[i]); 63 } 64 for(int i = 1; i <= N; ++i){ 65 for(int j = i + 1; j <= N; ++j){ 66 dis[i][j] = dis[j][i] = 67 sqrt((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j])); 68 cost[i][j] = cost[j][i] = fabs(z[i] - z[j]); 69 } 70 } 71 double mid,low = 0,high = 1e7; 72 while(fabs(high - low) > eps){ 73 mid = getmid(low,high); 74 //printf("mid : %.3f\n",mid); 75 if(Prim(mid)) 76 high = mid; 77 else 78 low = mid; 79 } 80 printf("%.3f\n",mid); 81 } 82 return 0; 83 }