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

题解:

0/1分数规划,二分mid

转化为是否存在一组解

使得∑vi-mid*∑ci<=0

即,每个格线有一个边权,每个格有权,是否能找到一个封闭的图形,使得内部和-边权和>0

发现和一般的不同的是,每个元素不是可以直接访问然后取值的。

因为还有格线和封闭起来的块的问题。

假设先不管块的值。

我们发现题目是一个从某个点出发,再回到某个点,然后判断是否有一条>0的路径。

即,图中有没有正环。

那么,块的值怎么办?

可以前缀差分!!

sum[i][j]表示,∑val[1~i][j]

对于一个横边:(i,j)->(i,j+1),边权是:mid*c+sum[i][j]

(i,j)->(i,j-1),边权是:mid*c-sum[i][j]

竖边就是mid*c

那么对于一个闭合封闭图形,必然可以把块的贡献看作是一列一列的。

并且,如果这是一个正环,那么存在从左下角出发往右走再绕回来,然后边权之和恰好有∑sum[i][j]-sum[i-p][j]

就差分出来格内部的权值和了。

注意,最短路的时候,为了卡精度,但是赋值时不能dis[dx][dy]=dis[x][y]+w-eps或者+eps

eps只在比较的时候用,赋值就不能用了。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=;
const double eps=0.000001;
int n,m;
int val[N][N];
int sum[N][N];
int mv[][]={{+,},{-,},{,+},{,-}};
int co[N][N][];
double dis[N][N];
bool vis[N][N];
int in[N][N];//ci in queue
struct node{
int has,x,y;
};
queue<node>q;
double mid;
bool spfa(){
while(!q.empty()) q.pop();
node st;
st.has=,st.x=,st.y=;
dis[][]=0.00;
q.push(st);
while(!q.empty()){
node now=q.front();q.pop();
vis[now.x][now.y]=;
if(now.has>(n+)*(m+)+) return true;
for(int i=;i<;i++){
int dx=now.x+mv[i][],dy=now.y+mv[i][];
if(dx<||dx>n) continue;
if(dy<||dy>m) continue;
double w=-1.0*mid*co[now.x][now.y][i];
if(i==) w+=sum[now.x][now.y+];
if(i==) w-=sum[now.x][now.y];
if(dis[dx][dy]+0.0001<dis[now.x][now.y]+w){
dis[dx][dy]=dis[now.x][now.y]+w;
in[dx][dy]++;
if(in[dx][dy]>(n+)*(m+)+) return true;
if(!vis[dx][dy]){
vis[dx][dy]=;
node tmp;
tmp.has=now.has+;
tmp.x=dx,tmp.y=dy;
q.push(tmp);
}
}
}
}
return false;
}
bool che(){
memset(dis,0xcf,sizeof dis);
memset(in,,sizeof in);
memset(vis,,sizeof vis);
if(spfa()) return true;
}
int main(){
scanf("%d%d",&n,&m);
int mx=;
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
scanf("%d",&val[i][j]);
mx+=val[i][j];
sum[i][j]=sum[i-][j]+val[i][j];
}
}int t;
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
scanf("%d",&t);
co[i][j-][]=co[i][j][]=t;
}
}
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
scanf("%d",&t);
co[i-][j][]=co[i][j][]=t;
}
}
double l=0.00,r=1.0*mx;
double ans;
while(r-l>eps){
mid=(l+r)/2.0;
if(che()) l=mid,ans=mid;
else r=mid;
}
printf("%.3lf",ans);
return ;
}

bzoj3232圈地游戏——0/1分数规划+差分建模+判环的更多相关文章

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

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

  2. Bzoj1486/洛谷P3199 最小圈(0/1分数规划+spfa)/(动态规划+结论)

    题面 Bzoj 洛谷 题解(0/1分数规划+spfa) 考虑\(0/1\)分数规划,设当前枚举到的答案为\(ans\) 则我们要使(其中\(\forall b_i=1\)) \[ \frac{\sum ...

  3. bzoj 3597: [Scoi2014]方伯伯运椰子 0/1分数规划

    3597: [Scoi2014]方伯伯运椰子 Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 144  Solved: 78[Submit][Status ...

  4. poj 2976 Dropping tests 0/1分数规划

    0/1分数规划问题,用二分解决!! 代码如下: #include<iostream> #include<stdio.h> #include<algorithm> # ...

  5. LOJ 3089 「BJOI2019」奥术神杖——AC自动机DP+0/1分数规划

    题目:https://loj.ac/problem/3089 没想到把根号之类的求对数变成算数平均值.写了个只能得15分的暴力. #include<cstdio> #include< ...

  6. poj2728 Desert King【最优比率生成树】【Prim】【0/1分数规划】

    含[最小生成树Prim]模板. Prim复杂度为$O(n^2),适用于稠密图,特别是完全图的最小生成树的求解.   Desert King Time Limit: 3000MS   Memory Li ...

  7. POJ - 2976 Dropping tests && 0/1 分数规划

    POJ - 2976 Dropping tests 你有 \(n\) 次考试成绩, 定义考试平均成绩为 \[\frac{\sum_{i = 1}^{n} a_{i}}{\sum_{i = 1}^{n} ...

  8. [SDOI2017]新生舞会 0/1分数规划

    ---题面--- 题解: 0/1分数规划,,,但是竟然有诡异的精度问题???因为这个被卡了好久 中途还写过一次KM,,,结果陷入死循环,,,我大概是写了一个假KM,,,于是放弃KM,回来调费用流 这个 ...

  9. Bzoj4753/洛谷P4432 [JSOI2016]最佳团体(0/1分数规划+树形DP)

    题面 Bzoj 洛谷 题解 这种求比值最大就是\(0/1\)分数规划的一般模型. 这里用二分法来求解最大比值,接着考虑如何\(check\),这里很明显可以想到用树形背包\(check\),但是时间复 ...

随机推荐

  1. Java开发工程师(Web方向) - 01.Java Web开发入门 - 第5章.Git

    第5章--Git 版本控制简介 VCS (version control system) 版本控制系统:记录若干文件的修订记录的系统,帮助查阅/回到某个历史版本 LVCS本地 CVCS集中式(Cent ...

  2. python 终极篇 --- form组件 与 modelForm

                                                           form组件                                       ...

  3. leetcode-岛屿的个数

    岛屿的个数 给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量.一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的.你可以假设网格的四个边均被水包围. 示例 ...

  4. python常用命令—终端安装win32的两种方法

    1, pip install pywin32 2, pip install pypiwin32

  5. spring boot 下使用@ConponentScan注解遇到的问题

    问题描述 如果你心急看结果,请直接到本文末尾 今天使用了注解操作spring boot,一开始程序无法启动,提示无法找到一个注解注入的类,查询网上,有人说使用@ConponetScan注解,可以指定需 ...

  6. solidity中的memory和 storage详解

    Solidity是一种智能合约高级语言,运行在Ethereum虚拟机(EVM)之上.这里我会讲解一下关键字storage和memory的区别. storage的结构是在合约部署创建时,根据你的合约中状 ...

  7. 如何让thinkpad X1C 用U盘 安装上专业版win10

    1 BIOS内置了文件 会导致win10 iso默认装家庭版 2 给iso 的resouse 目录中增加文件ei.cfg 3 内容如下 [EditionID]Professional[Channel] ...

  8. Python面向对象-类成员

    类的成员可以分为三大类:字段.方法和属性: 注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存中就有多少个普通字段.而其他的成员,则都是保存在类中,即:无论对象的多少,在 ...

  9. Nodejs第一天-{Nodejs基础 深刻理解浏览器 环境变量 基础语法}

    Nodejs第一天 1.什么是Nodejs ​ Nodejs是一个可以运行(解析)ECMAScript的环境; ​ ECMAScript是规定了一些列的语法 ,这些语法想要解析的执行就需要放在某个环境 ...

  10. 20145214 《Java程序设计》第7周学习总结

    20145214 <Java程序设计>第7周学习总结 教材学习内容总结 时间的度量 格林威治标准时间(GMT),现已不作为标准时间使用,即使标注为GMT(格林威治时间),实际上谈到的的是U ...