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. Siki_Unity_1-6_C#编程初级教程(未学)

    Unity 1-6 C#编程初级教程 任务1:C#和.Net框架 C#是.Net里的一个成分 2002年微软发布第一个.Net框架(多平台,行业标准,安全性) .Net框架 IDE编程工具 --产生- ...

  2. linux 学习总结---- mysql 总结

    用户的创建 ---->修改 ---->删除用户 create alter drop (数据定义语言 DDL) 授权: insert update delete grant *.* revo ...

  3. [python]np.loadtxt报错

    np.loadtxt报错 通过pandas生成的cvs数据利用nump.loadtxt读取的时候 tmp = np.loadtxt('test.csv', dtype=np.str, delimite ...

  4. 数据库Mysql的学习(六)-子查询和多表操作

    )*0.05 WHERE card_id ='20121xxxxxx'; //子查询就是一个嵌套先计算子查询 SELECT * FROM borrow WHERE book_id =(SELECT b ...

  5. spark写入ES(动态模板)

    使用es-hadoop插件,主要使用elasticsearch-spark-20_2.11-6.2.x.jar 官网:https://www.elastic.co/guide/en/elasticse ...

  6. hibernate提示Unknown entity: :xxx

    错误提示: org.hibernate.MappingException: Unknown entity: org.dao.po.Role at org.hibernate.internal.Sess ...

  7. CryptoZombies学习笔记——Lesson5

    chapter1:token代币 简而言之,通证就是支持交易的包含一系列规范的函数接口的一个智能合约,发币可以用ERC20标准,但是像僵尸这种非同质化代币,需要用ERC721标准 chapter2:e ...

  8. NYOJ 35 表达式求值(逆波兰式求值)

    http://acm.nyist.net/JudgeOnline/problemset.php?typeid=4 NYOJ 35 表达式求值(逆波兰式求值) 逆波兰式式也称后缀表达式. 一般的表达式求 ...

  9. Thunder团队第六周 - Scrum会议3

    Scrum会议3 小组名称:Thunder 项目名称:i阅app Scrum Master:李传康 工作照片: 参会成员: 王航:http://www.cnblogs.com/wangh013/ 李传 ...

  10. Java接口与继承作业

    为什么子类的构造方法在运行之前,必须调用父类的构造方法?能不能反过来?为什么不能反过来? 因为子类继承了父类,那么就默认的含有父类的公共成员方法和公共成员变量,这些方法和变量在子类里不再重复声明.如果 ...