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. OIDC in Angular 6

    参照 草根专栏- ASP.NET Core + Ng6 实战:https://v.qq.com/x/page/i07702h18nz.html 1. OIDC-Client https://githu ...

  2. JDBC中使用Properties类及配置文件的操作

    同时发布于:https://blog.csdn.net/Activity_Time/article/details/81149710 一.properties配置文件 开发中获得连接的4个参数(驱动. ...

  3. PHP计算两个已知经纬度之间的距离

    /** *求两个已知经纬度之间的距离,单位为千米 *@param lng1,lng2 经度 *@param lat1,lat2 纬度 *@return float 距离,单位千米 **/ privat ...

  4. 从Softmax回归到Logistic回归

    Softmax回归是Logistic回归在多分类问题上的推广,是有监督的. 回归的假设函数(hypothesis function)为,我们将训练模型参数,使其能够最小化代价函数: 在Softmax回 ...

  5. iis 10 重新注册iis

    iis 10 使用该命令 提示 版本不支持 C:\WINDOWS\system32>c:\windows\microsoft.net\framework64\v4.0.30319\aspnet_ ...

  6. 迭代器类型:iterator & const_iterator

    vector<int> ivec{1, 3, 4, 1, 3, 4}; vector<int>::iterator iter; // iter能读写vector<int& ...

  7. 王者荣耀交流协会beta冲刺贡献分分配结果

    根据原来约定的(贡献分分配规则){http://www.cnblogs.com/gaoyb348/p/7828523.html} 总共20个任务,一共35分,那么一个任务1.75分. 冉华完成了9个任 ...

  8. Java中的增强for循环

    增强 for 循环 1. 增强的 for 循环对于遍历 Array 或 Collection 的时候相当方便. import java.util.*; public class Test { publ ...

  9. android入门 — ListView的优化

    ListView的运行效率是比较低的,因为在getView()中每次都会将整个布局重新加载一遍,当ListView快速滚动的时候就会成为性能瓶颈. 调用View中的findViewById()方法获取 ...

  10. 3dContactPointAnnotationTool开发日志(十六)

      调了一上午才发现是把下面这个函数: private float DivideTriangle(int []triangle,out int []outTriangle,List<Vector ...