wenbao与最优比率生成树
推荐博客
http://www.cnblogs.com/KirisameMarisa/p/4187637.html
-----------------------------------------------------------
http://poj.org/problem?id=2976
二分
1 #include "iostream" 2 #include <algorithm> 3 #include <cmath> 4 #include <stdio.h> 5 using namespace std; 6 7 #define ll long long 8 #define eps 1e-8 9 const int maxn = 1009; 10 double a[maxn], b[maxn], d[maxn]; 11 int n, k; 12 13 double cheak(double mid) { 14 for(int i = 0; i < n; ++i) d[i] = a[i]-mid*b[i]; 15 sort(d, d+n); 16 double sum = 0; 17 for(int i = 0; i < k; ++i) sum += d[n-1-i]; 18 return sum; 19 } 20 21 int main() { 22 #ifdef wenbao 23 freopen("in", "r", stdin); 24 #endif 25 while(~scanf("%d%d", &n, &k)) { 26 if(n == 0 && k == 0) break; 27 k = n-k; 28 for(int i = 0; i < n; ++i) scanf("%lf", &a[i]); 29 for(int i = 0; i < n; ++i) scanf("%lf", &b[i]); 30 double l = 0.0, r = 1000000000.0, mid; 31 while(fabs(r-l) > eps) { 32 mid = (r+l)/2.0; 33 if(cheak(mid) >= 0) l = mid; 34 else r = mid; 35 } 36 printf("%.0lf\n", floor(l*100+0.5)); 37 } 38 return 0; 39 }
迭代
1 #include "iostream" 2 #include <algorithm> 3 #include <cmath> 4 #include <stdio.h> 5 using namespace std; 6 7 #define ll long long 8 #define eps 1e-8 9 const int maxn = 1009; 10 double a[maxn], b[maxn], d[maxn]; 11 int id[maxn], n, k; 12 13 bool cmp(int x, int y) { 14 return d[x] > d[y]; 15 } 16 17 double cheak(double l) { 18 for(int i = 0; i < n; ++i) d[i] = a[i]-l*b[i], id[i] = i; 19 sort(id, id+n, cmp); 20 double sum1 = 0.0, sum2 = 0.0; 21 for(int i = 0; i < n-k; ++i) sum1 += a[id[i]], sum2 += b[id[i]]; 22 return sum1/sum2; 23 } 24 25 int main() { 26 #ifdef wenbao 27 freopen("in", "r", stdin); 28 #endif 29 while(~scanf("%d%d", &n, &k)) { 30 if(n == 0 && k == 0) break; 31 for(int i = 0; i < n; ++i) scanf("%lf", &a[i]); 32 for(int i = 0; i < n; ++i) scanf("%lf", &b[i]); 33 double l = 0.0, r; 34 while(1) { 35 r = cheak(l); 36 if(fabs(r-l) < eps) break; 37 l = r; 38 } 39 printf("%.0lf\n", floor(l*100+0.5)); 40 } 41 return 0; 42 }
----------------------------------------------------------
http://poj.org/problem?id=2728
最小生树上的最优
二分
1 #include "iostream" 2 #include <queue> 3 #include <string.h> 4 #include <cmath> 5 #include <stdio.h> 6 using namespace std; 7 8 #define eps 1e-4 9 const int maxn = 1009; 10 int n; 11 double a[maxn], b[maxn], c[maxn], cost[maxn][maxn], di[maxn][maxn], dist[maxn]; 12 13 double prim(double x) { 14 double ans = 0.0; 15 for(int i = 2; i <= n; ++i){ 16 dist[i] = cost[1][i] - x*di[1][i]; 17 } 18 dist[1] = -1; 19 int k; 20 for(int i = 2; i <= n; ++i){ 21 double mi = 10000000000000.0; 22 for(int j = 1; j <= n; ++j){ 23 if(dist[j] != -1 && dist[j] < mi){ 24 mi = dist[j]; 25 k = j; 26 } 27 } 28 dist[k] = -1; 29 ans += mi; 30 for(int j = 1; j <= n; ++j){ 31 if(dist[j] != -1 && dist[j] > cost[k][j] - x*di[k][j]){ 32 dist[j] = cost[k][j] - x*di[k][j]; 33 } 34 } 35 } 36 return ans; 37 } 38 39 int main(){ 40 #ifdef wenbao 41 freopen("in", "r", stdin); 42 #endif 43 while(~scanf("%d", &n) && n){ 44 for(int i = 1; i <= n; ++i){ 45 scanf("%lf%lf%lf", &a[i], &b[i], &c[i]); 46 for(int j = 1; j < i; ++j){ 47 double x = (a[i]-a[j])*(a[i]-a[j]) + (b[i]-b[j])*(b[i]-b[j]); 48 cost[j][i] = cost[i][j] = (c[i] > c[j]) ? c[i] - c[j] : c[j] - c[i]; 49 di[i][j] = di[j][i] = sqrt(x); 50 } 51 } 52 double l = 0.0, r = 100000.0, mid; 53 while((r-l) > eps){ 54 //cout<<l<<"&&"<<r<<endl; 55 mid = (l+r)/2.0; 56 if(prim(mid) >= 0){ 57 l = mid; 58 }else{ 59 r = mid; 60 } 61 } 62 printf("%.3lf\n", l); 63 } 64 return 0; 65 }
迭代
1 #include "iostream" 2 #include <queue> 3 #include <string.h> 4 #include <cmath> 5 #include <stdio.h> 6 using namespace std; 7 8 #define eps 1e-4 9 const int maxn = 1009; 10 int n, id[maxn]; 11 double a[maxn], b[maxn], c[maxn], cost[maxn][maxn], di[maxn][maxn], dist[maxn]; 12 bool vis[maxn]; 13 14 15 double prim(double x) { 16 memset(vis, false, sizeof(vis)); 17 for(int i = 2; i <= n; ++i) dist[i] = cost[1][i] - di[1][i]*x, id[i] = 1; 18 vis[1] = true, dist[1] = 0; 19 int k; 20 double sum1 = 0.0, sum2 = 0.0; 21 for(int i = 2; i <= n; ++i){ 22 double mi = 100000000000.0; 23 for(int j = 2; j <= n; ++j){ 24 if(!vis[j] && dist[j] < mi){ 25 k = j, mi = dist[j]; 26 } 27 } 28 vis[k] = true; 29 sum1 += cost[id[k]][k], sum2 += di[id[k]][k]; 30 for(int j = 2; j <= n; ++j){ 31 if(!vis[j] && dist[j] > cost[k][j] - di[k][j]*x){ 32 dist[j] = cost[k][j] - di[k][j]*x; 33 id[j] = k; 34 } 35 } 36 } 37 return sum1/sum2; 38 } 39 40 int main(){ 41 #ifdef wenbao 42 freopen("in", "r", stdin); 43 #endif 44 while(~scanf("%d", &n) && n){ 45 for(int i = 1; i <= n; ++i){ 46 scanf("%lf%lf%lf", &a[i], &b[i], &c[i]); 47 for(int j = 1; j < i; ++j){ 48 double x = (a[i]-a[j])*(a[i]-a[j]) + (b[i]-b[j])*(b[i]-b[j]); 49 cost[j][i] = cost[i][j] = (c[i] > c[j]) ? c[i] - c[j] : c[j] - c[i]; 50 di[i][j] = di[j][i] = sqrt(x); 51 } 52 } 53 double l = 0.0, r; 54 while(1){ 55 r = prim(l); 56 if(fabs(r-l) < eps){ 57 break; 58 }else{ 59 l = r; 60 } 61 } 62 printf("%.3lf\n", l); 63 } 64 return 0; 65 }
----------------------------------------------------------
-----------------------------------------------------------
只有不断学习才能进步!