0/1分数规划

求下式的最大值:

inai×xiinbi×xi

也就是 对任意的x

inai×xiinbi×xians

二分一个值mid 问题转化是否存在一组x 使

in(aibi×mid)×xi0

如果存在 说明二分的值小了 如果不存在 说明二分的值大了

所以一求上面式子的最大值即可
这是0/1分数规划问题的关键: 求出满足题意的最大值

最优比例生成树

每个边有连个权值 求最优比例生成树
沙漠之王

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int N=1010;
const int INF=0x3f3f3f3f;
const double eps=1e-6;
int read()
{
	int x=0,f=0,c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
	return f?-x:x;
}

int n; 

struct Point
{
	int x,y,h;
}p[N];
double a[N][N],b[N][N],e[N][N];
double getdis(int x,int y,int x_,int y_){ return sqrt( (x-x_)*(x-x_)+(y-y_)*(y-y_) ); }
double dis[N];
bool vis[N];
//稠密图还真的不能加堆优化 加上堆优化后变成mlogn prim的优势不再显著
//double:: 1e37
bool check(double mid)
{
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			e[i][j]=a[i][j]-mid*b[i][j];
	for(int i=1;i<=n;i++) dis[i]=INF,vis[i]=0;
	dis[1]=0;
	for(int i=1;i<=n;i++)
	{
		int x=0;
		for(int j=1;j<=n;j++)
			if(!vis[j]&&(!x||dis[j]<dis[x])) x=j;//这种查找方式一定要处理第一次查找的情况
		 vis[x]=1;
		 for(int j=1;j<=n;j++)
		 	if(!vis[j]) dis[j]=min(dis[j],e[x][j]);
	}
	double ret=0;
	for(int i=1;i<=n;i++) ret+=dis[i];
	return ret<0;
}

int main()
{
	while( (n=read())!=0)
	{
		for(int i=1;i<=n;i++) p[i].x=read(),p[i].y=read(),p[i].h=read();
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
			{
				a[i][j]=abs(p[i].h-p[j].h); 
				b[i][j]=getdis(p[i].x,p[i].y,p[j].x,p[j].y);
			}	
		double l=0,r=1e11;
		while(r-l>eps)
		{
			double mid=(l+r)/2;
			if(check(mid)) r=mid;
			else l=mid;
		}
		printf("%.3lf\n",r);
	}
	return 0;
}
posted @   __iostream  阅读(57)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示