3232: 圈地游戏

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 966  Solved: 466
[Submit][Status][Discuss]

Description

DZY家的后院有一块地,由N行M列的方格组成,格子内种的菜有一定的价值,并且每一条单位长度的格线有一定的费用。
DZY喜欢在地里散步。他总是从任意一个格点出发,沿着格线行走直到回到出发点,且在行走途中不允许与已走过的路线有任何相交或触碰(出发点除外)。记这条封闭路线内部的格子总价值为V,路线上的费用总和为C,DZY想知道V/C的最大值是多少。

Input

第一行为两个正整数n,m。
接下来n行,每行m个非负整数,表示对应格子的价值。
接下来n+1行,每行m个正整数,表示所有横向的格线上的费用。
接下来n行,每行m+1个正整数,表示所有纵向的格线上的费用。
(所有数据均按从左到右,从上到下的顺序输入,参见样例和配图)

Output

 
输出一行仅含一个数,表示最大的V/C,保留3位小数。

Sample Input

3 4
1 3 3 3
1 3 1 1
3 3 1 0
100 1 1 1
97 96 1 1
1 93 92 92
1 1 90 90
98 1 99 99 1
95 1 1 1 94
1 91 1 1 89

Sample Output

1.286

HINT

Source

jcvb提供

想法:$max(\frac{\sum D}{\sum C})$,一般都是用分数规划求。

对于一个环,某一行\列所选择的边都是偶数的。被包含的部分就像左右括号包含一样。于是这样建图:

横边:

  ①$(i,j)->(i,j+1):C_i=边花费,D_i=sum[i][j](即该列的前缀和)$

  ②$(i,j)->(i,j-1):C_i=边花费,D_i=-sum[i][j](即该列的前缀和)$

竖边:

  ①$(i,j)->(i+1,j):C_i=边花费,D_i=0$

  ②$(i,j)->(i-1,j):C_i=边花费,D_i=0$

然后判断合法,即是判断图中是否有非负环,可以权值取反后DFS_spfa求负环(这里有一个比较快的求法)。

另一个解法:考虑如果相邻的格子被同时选中,那么中间的边的费用就不会算进来了,于是变成最小割模型。

#include<cstdio>

typedef long long ll;
template<class T>
inline void read(T&x)
{
x=;bool f=;char c=getchar();
while((c<''||c>'')&&c!='-')c=getchar(); if(c=='-')f=,c=getchar();
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
x=f?-x:x;
}
const int MAXN();
const double eps(1e-);
int n,m,val[MAXN][MAXN],row[MAXN][MAXN],line[MAXN][MAXN],sum;
double ans;
struct Node{int nd,nx,v,c;}bot[MAXN*MAXN<<];int tot,first[MAXN*MAXN];
int P(int x,int y){return (x-)*(m+)+y;}
void add(int a,int b,int v,int c){bot[++tot]=(Node){b,first[a],v,c};first[a]=tot;}
void build()
{
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)val[i][j]+=val[i-][j];
for(int i=;i<=n+;i++)
for(int j=;j<=m;j++)
add(P(i,j),P(i,j+),val[i-][j],row[i][j]),
add(P(i,j+),P(i,j),-val[i-][j],row[i][j]);
for(int i=;i<=n;i++)
for(int j=;j<=m+;j++)
add(P(i,j),P(i+,j),,line[i][j]),
add(P(i+,j),P(i,j),,line[i][j]);
}
double dis[MAXN*MAXN],limt;
bool vis[MAXN*MAXN],flag;
void dfs(int x)
{
vis[x]=true;
for(int v=first[x];v;v=bot[v].nx)
if(dis[bot[v].nd]>dis[x]+bot[v].c*limt-bot[v].v+eps)
{
if(vis[bot[v].nd]){flag=true;return;};
dis[bot[v].nd]=dis[x]+bot[v].c*limt-bot[v].v;
dfs(bot[v].nd);if(flag)return;
}
vis[x]=false;
}
bool ok(double mid)
{
limt=mid; flag=false; for(int i=;i<=(n+)*(m+);i++)dis[i]=vis[i]=;
for(int i=;i<=(n+)*(m+);i++)
{
dfs(i);if(flag)return true;
}
return false;
}
int main()
{
// freopen("C.in","r",stdin);
// freopen("C.out","w",stdout);
read(n);read(m);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)read(val[i][j]),sum+=val[i][j];
for(int i=;i<=n+;i++)
for(int j=;j<=m;j++)read(row[i][j]);
for(int i=;i<=n;i++)
for(int j=;j<=m+;j++)read(line[i][j]);
build();
for(double l=,r=sum,mid;l+eps<r;)
if(ok(mid=(l+r)/))l=mid,ans=mid;else r=mid;
printf("%.3lf",ans);
return ;
}

BZOJ 3232: 圈地游戏 分数规划+判负环的更多相关文章

  1. bzoj 3232: 圈地游戏

    bzoj 3232: 圈地游戏 01分数规划,就是你要最大化\(\frac{\sum A}{\sum B}\),就二分这个值,\(\frac{\sum A}{\sum B} \geq mid\) \( ...

  2. bzoj 3232 圈地游戏——0/1分数规划(或网络流)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3232 当然是0/1分数规划.但加的东西和减的东西不在一起,怎么办? 考虑把它们合在一起.因为 ...

  3. bzoj 3232: 圈地游戏 01分数规划

    题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=3232 题解: 首先我们看到这道题让我们最优化一个分式. 所以我们应该自然而然地想到01分 ...

  4. bzoj 3232 圈地游戏 —— 01分数规划+最小割建图(最大权闭合子图)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3232 心烦意乱的时候调这道题真是...越调越气,就这样过了一晚上... 今天再认真看看,找出 ...

  5. bzoj 3232: 圈地游戏【分数规划+最小割】

    数组开小导致TTTTTLE-- 是分数规划,设sm为所有格子价值和,二分出mid之后,用最小割来判断,也就是判断sm-dinic()>=0 这个最小割比较像最大权闭合子图,建图是s像所有点连流量 ...

  6. 【BZOJ3232】圈地游戏 分数规划+最小割

    [BZOJ3232]圈地游戏 Description DZY家的后院有一块地,由N行M列的方格组成,格子内种的菜有一定的价值,并且每一条单位长度的格线有一定的费用. DZY喜欢在地里散步.他总是从任意 ...

  7. [bzoj1486][HNOI2009]最小圈——分数规划+spfa+负环

    题目 传送门 题解 这个题是一个经典的分数规划问题. 把题目形式化地表示,就是 \[Minimize\ \lambda = \frac{\sum W_{i, i+1}}{k}\] 整理一下,就是 \[ ...

  8. [bzoj3597][scoi2014]方伯伯运椰子——分数规划,负环

    题解 目标就是 \[Maximize\ \lambda = \frac{X-Y}{k}\] 按照分数规划的一般规律, 构造: \[g(\lambda) = \lambda k + Y - X\] 由于 ...

  9. BZOJ 4898 [APIO2017] 商旅 | SPFA判负环 分数规划

    BZOJ 4898 [APIO2017] 商旅 | SPFA判负环 分数规划 更清真的题面链接:https://files.cnblogs.com/files/winmt/merchant%28zh_ ...

随机推荐

  1. 转-tcp建立和释放详解

    建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. [更新于2017.01.04 ]该部分内容配图有误,请大家见谅,正确的配图如下,错误配图也不删 ...

  2. hbase&nbsp;multiple&nbsp;SLF4J&amp;n…

    hbase multiple SLF4J bindings 警告 hbase shell 和命令操作中经常有个烦人的警告,说SLF4J有多个绑定: hbase(main):003:0> list ...

  3. 我也来Show一下我的VisualStudio2017

    1.首先,在微软官方网站下载VS2017的安装程序,后续的安装将通过这个安装程序来引导.这里有三个版本可供选择:社区版.专业版和企业版,社区版免费,专业版和企业版可以免费体验,之后收费,当然,在中国盗 ...

  4. [UE4]Component相关常用API

    http://www.dawnarc.com/2017/02/ue4component%E7%9B%B8%E5%85%B3%E5%B8%B8%E7%94%A8api/ Actor.h //获取第一个与 ...

  5. 分享微信h5支付经验

    <?php //use Flight; /** * 微信支付服务器端下单 * 微信APP支付文档地址: https://pay.weixin.qq.com/wiki/doc/api/app.ph ...

  6. 解决Idea项目启动报错:程序包javax.servlet.http不存在

    报错信息 在没有使用maven的时候,web项目从远程仓库获取下以后,起一次启动往往会报错javax.servlet.http程序包找不到,随之而来的java基础包都将不能使用,报错信息如下: 解决方 ...

  7. 36小时极客嘉年华!FISCO BCOS黑客马拉松报名启动

    FISCO BCOS是完全开源的联盟区块链底层技术平台,由金融区块链合作联盟(深圳)(简称金链盟)成立开源工作组通力打造.开源工作组成员包括博彦科技.华为.深证通.神州数码.四方精创.腾讯.微众银行. ...

  8. js中的面向对象程序设计

    面向对象的语言有一个标志,即拥有类的概念,抽象实例对象的公共属性与方法,基于类可以创建任意多个实例对象,一般具有封装.继承.多态的特性!但JS中对象与纯面向对象语言中的对象是不同的,ECMA标准定义J ...

  9. 线程池(3)Executors.newCachedThreadPool

    例子: ExecutorService es = Executors.newCachedThreadPool(); try { for (int i = 0; i < 20; i++) { Ru ...

  10. vs2012 support BI

    Microsoft SQL Server Data Tools - Business Intelligence for Visual Studio 2012 http://www.microsoft. ...