博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 2728 Desert King (算竞进阶习题)
阅读量:5263 次
发布时间:2019-06-14

本文共 2539 字,大约阅读时间需要 8 分钟。

最小生成树 + 01分数规划

好烦的卡精度题,调了一下午。。

题意大概就是给你一张稠密图,每条边都有收益和花费,要求一个花费之和与收益之和的比值和最小的生成树。

当然我们可以看成收益之和与花费之和的比值最大的生成树。。

这显然是一个01分数规划问题。然后二分枚举猜测的L值跑最大生成树就行了,若最大生成树大于等于0,代表我们的最大值大于等于L,于是mid = l,若最大生成树小于0,代表我们的最大值小于L, 于是mid = r。

#include 
#include
#include
#include
#include
#include
#define INF 0x3f3f3f3f#define full(a, b) memset(a, b, sizeof a)using namespace std;typedef long long ll;inline int lowbit(int x){ return x & (-x); }inline int read(){ int X = 0, w = 0; char ch = 0; while(!isdigit(ch)) { w |= ch == '-'; ch = getchar(); } while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar(); return w ? -X : X;}inline int gcd(int a, int b){ return a % b ? gcd(b, a % b) : b; }inline int lcm(int a, int b){ return a / gcd(a, b) * b; }template
inline T max(T x, T y, T z){ return max(max(x, y), z); }template
inline T min(T x, T y, T z){ return min(min(x, y), z); }template
inline A fpow(A x, B p, C lyd){ A ans = 1; for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd; return ans;}const int N = 1005;const double eps = 1e-7;int n;double x[N], y[N], z[N];double dist[N][N], cost[N][N], cur[N][N], mst, d[N];bool vis[N];inline double getDis(double x1, double y1, double x2, double y2){ return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));}inline void build(double mid){ for(int i = 1; i <= n; i ++){ for(int j = 1; j <= n; j ++) cur[i][j] = -INF; } for(int i = 1; i <= n; i ++){ for(int j = 1; j <= n; j ++){ if(i == j) continue; cur[i][j] = dist[i][j] - mid * cost[i][j]; } }}inline void prim(){ for(int i = 1; i <= n; i ++){ d[i] = -INF; vis[i] = false; } d[1] = mst = 0.0; for(int i = 1; i < n; i ++){ int x = 0; for(int j = 1; j <= n; j ++){ if(!vis[j] && (x == 0 || d[j] > d[x])) x = j; } vis[x] = true; for(int j = 1; j <= n; j ++){ if(!vis[j]) d[j] = max(d[j], cur[x][j]); } } for(int i = 2; i <= n; i ++) mst += d[i];}inline bool check(){ prim(); return mst >= 0.0;}int main(){ ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); while(cin >> n && n){ for(int i = 1; i <= n; i ++) cin >> x[i] >> y[i] >> z[i]; for(int i = 1; i <= n; i ++){ for(int j = i + 1; j <= n; j ++){ dist[i][j] = dist[j][i] = getDis(x[i], y[i], x[j], y[j]); cost[i][j] = cost[j][i] = fabs(z[i] - z[j]); } } double l = 0.0, r = 40.0; while(r - l >= eps){ double mid = (l + r) / 2; build(mid); if(check()) l = mid; else r = mid; } printf("%.3lf\n", 1 / l); } return 0;}

转载于:https://www.cnblogs.com/onionQAQ/p/10826689.html

你可能感兴趣的文章
android 签名
查看>>
android:scaleType属性
查看>>
SuperEPC
查看>>
mysql-5.7 innodb 的并行任务调度详解
查看>>
shell脚本
查看>>
Upload Image to .NET Core 2.1 API
查看>>
Js时间处理
查看>>
Java项目xml相关配置
查看>>
三维变换概述
查看>>
vue route 跳转
查看>>
【雷电】源代码分析(二)-- 进入游戏攻击
查看>>
Entityframework:“System.Data.Entity.Internal.AppConfig”的类型初始值设定项引发异常。...
查看>>
Linux中防火墙centos
查看>>
mysql新建用户,用户授权,删除用户,修改密码
查看>>
FancyCoverFlow
查看>>
JS博客
查看>>
如何设置映射网络驱动器的具体步骤和方法
查看>>
ASP.NET WebApi 基于OAuth2.0实现Token签名认证
查看>>
283. Move Zeroes把零放在最后面
查看>>
Visual Studio Code 打开.py代码报Linter pylint is not installed解决办法
查看>>