bzoj-3232 圈地游戏

141 篇文章 0 订阅
75 篇文章 0 订阅

题意:

在一个n*m的网格里,边上有花费,格里有权值;
从任意一个点开始绕一圈,绕一个简单环出来,里面的所有格子就是收益;
求最大的收益/花费;

所有数<=100;


题解:

考虑01分数规划的方式,但是花费和权值不在一起;

那么考虑将格内的权值转化到边上;

实际上将边有向化,按边方向左面一行的权值为正,右面为负,加起来作为选了这条边的权值;

这样在围成一个环的过程中会将外面的点消掉,而里面的点是四倍大小;

问题转化成二分答案,对一个图进行check,考虑其中有没有正权的环;

上一个BF判断就好了;

时间复杂度O(n^2*m^2*log400);

二分上界定为400就可以了,别忘了答案要除4;


代码:


#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 110
using namespace std;
int to[N*N<<2],next[N*N<<2],val[N*N<<2],cost[N*N<<2],head[N*N],tot;
int n,m,L[N][N],U[N][N],num[N][N];
double dis[N*N];
void add(int x,int y,int v,int c)
{
	to[++tot]=y,val[tot]=v,cost[tot]=c,next[tot]=head[x],head[x]=tot;
}
bool check(double L)
{
	memset(dis,0,sizeof(dis));
	int i,j,k,x,y;
	for(k=1;k<=(n+1)*(m+1);k++)
	{
		bool flag=0;
		for(x=1;x<=(n+1)*(m+1);x++)
		{
			for(i=head[x];i;i=next[i])
			{
				y=to[i];
				if(dis[y]>dis[x]+L*cost[i]-val[i])
					dis[y]=dis[x]+L*cost[i]-val[i],flag=1;
			}
		}
		if(!flag)
		return 0;
	}
	return 1;
}
int main()
{
	int i,j,k,x;
	scanf("%d%d",&n,&m);
	for(i=0,k=0;i<=n;i++)
		for(j=0;j<=m;j++)
			num[i][j]=++k;
	for(i=1,k=0;i<=n;i++)
	{
		for(j=1;j<=m;j++)
		{
			scanf("%d",&x);
			L[i][j]=L[i][j-1]+x;
			U[i][j]=U[i-1][j]+x;
		}
	}
	for(i=0;i<=n;i++)
	{
		for(j=1;j<=m;j++)
		{
			scanf("%d",&x);
			add(num[i][j-1],num[i][j],(U[i][j]<<1)-U[n][j],x);
			add(num[i][j],num[i][j-1],U[n][j]-(U[i][j]<<1),x);
		}
	}
	for(i=1;i<=n;i++)
	{
		for(j=0;j<=m;j++)
		{
			scanf("%d",&x);
			add(num[i-1][j],num[i][j],L[i][m]-(L[i][j]<<1),x);
			add(num[i][j],num[i-1][j],(L[i][j]<<1)-L[i][m],x);
		}
	}
	double l=0,r=400,mid;
	while(r-l>1e-5)
	{
		mid=(l+r)/2;
		if(check(mid))
			l=mid;
		else
			r=mid;
	}
	printf("%.3lf",l/4);
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值