最小割经典模型指的是“一堆元素进行选取,对于某个元素的取舍有代价或价值,对于某些对元素,选取后会有额外代价或价值”的经典最小割模型,建立倒三角进行最小割。
这个二分是显然的,一开始我也是想到了最小割的那个模型的但是我觉得他会不是一个圈我就否掉了,但是仔细想想的话会发现,如果是这样的话所得到的答案一定小于等于一个圈的答案(浓度),所以我们可定会得到最终答案,所以这样做是可以的,所以说要有宽松得正解的意识(泥沙俱下但沙子不影响我泥)。当时我否掉最小割以后就立马去想费用流了,然后想到建图后发现那样建图虽然不好跑费用流,但是SPFA判环还是很劲的,所以我就判了一发环。
在这里就顺便说一下SPFA判负(正)环吧。DFS的话就是判断一个点是否重复出现在DFS路径中,他有一个优化(没看呢),就叫他DFS+吧。然后他还有BFS版的,就是判断一个点是否重复入队n次(点数),但是不能判断是否被更新n次,这样有可能会出错(不用重边就可以做到)(也许可以分析是否可行但是不会很简单而且很难考虑周全),并且这两种方法的时间复杂度有些时候差距并不大只不过是一个常数。网上还有人说是进队次数大于入度,这个经试验证明是扯淡。还有另一种做法是判断到达次点的最短路径的边数等于n这个不仅很对还很快,就叫他BFS+吧。
对于这道题DFS会T,然而DFS+,BFS,以及BFS+均可过,而BFS+表现最优。这说明虽然找最短路方面BFS_SPFA找最短路比DFS_SPFA要好,但是在判环方面并不是DFS一定优于BFS,比如这道题,所以说BFS大法吼。

#include <cstdio>
#include <cstring>
#include <algorithm>
#define pos(a,b) (((a)-1)*(m+1)+(b))
typedef long double db;
const int N=;
const int P=N*N;
const int E=P*;
const db oo=-1e18;
const db eps=1e-;
const db ans_eps=1e-;
struct V{
int to,next;
db w;
}c[E];
int head[P],t;
inline void add(int x,int y,db z){
c[++t].to=y,c[t].next=head[x],head[x]=t,c[t].w=z;
}
db dis[P];
bool in[P];
int n,m,sum;
int val[N][N],cost1[N][N],cost2[N][N];
int q[P],front,back;
int cnt[P];
inline bool spfa(int s){
q[back++]=s,in[s]=true;
if(back==P)back=;
while(front!=back){
int x=q[front++];
in[x]=false;
if(front==P)front=;
for(int i=head[x];i;i=c[i].next)
if(dis[x]+c[i].w-dis[c[i].to]>eps){
dis[c[i].to]=dis[x]+c[i].w;
cnt[c[i].to]=cnt[x]+;
if(cnt[c[i].to]==sum)return true;
if(in[c[i].to]==false){
q[back++]=c[i].to;
in[c[i].to]=true;
if(back==P)back=;
}
}
}
return false;
}
inline bool check(db mid){
memset(head,,sizeof(head)),t=;
memset(in,,sizeof(in));
memset(cnt,,sizeof(cnt));
for(int i=;i<=sum;++i)dis[i]=oo;
for(int i=;i<=n+;++i)
for(int j=;j<=m+;++j){
if(j!=m+)
add(pos(i,j),pos(i,j+),-cost1[i][j]*mid+val[i][j]);
if(j!=)
add(pos(i,j),pos(i,j-),-cost1[i][j-]*mid-val[i][j-]);
if(i!=n+)
add(pos(i,j),pos(i+,j),-cost2[i][j]*mid);
if(i!=)
add(pos(i,j),pos(i-,j),-cost2[i-][j]*mid);
}
dis[sum/]=.;
return spfa(sum/);
}
int main(){
scanf("%d%d",&n,&m);
sum=(n+)*(m+);
for(int i=;i<=n;++i)
for(int j=;j<=m;++j)
scanf("%d",&val[i][j]);
for(int i=;i<=m;++i)
for(int j=n;j>;--j)
val[j][i]+=val[j+][i];
for(int i=;i<=n+;++i)
for(int j=;j<=m;++j)
scanf("%d",&cost1[i][j]);
for(int i=;i<=n;++i)
for(int j=;j<=m+;++j)
scanf("%d",&cost2[i][j]);
db l=.,r=.,mid,ans=.;
while(l+ans_eps<r){
mid=(l+r)*0.5;
if(check(mid))
ans=mid,l=mid;
else
r=mid;
}
printf("%.3f",(double)ans);
return ;
}

【BZOJ 3232】圈地游戏 二分+SPFA判环/最小割经典模型的更多相关文章

  1. BZOJ 3232: 圈地游戏 分数规划+判负环

    3232: 圈地游戏 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 966  Solved: 466[Submit][Status][Discuss] ...

  2. bzoj 3232: 圈地游戏

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

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

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

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

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

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

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

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

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

  7. bzoj 2132 圈地计划(黑白染色,最小割)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2132 [题意] 给定n*m个区域,建工业区价值A,建商业区价值B,如果(i,j)有k个 ...

  8. poj 2049(二分+spfa判负环)

    poj 2049(二分+spfa判负环) 给你一堆字符串,若字符串x的后两个字符和y的前两个字符相连,那么x可向y连边.问字符串环的平均最小值是多少.1 ≤ n ≤ 100000,有多组数据. 首先根 ...

  9. 2018.09.12 poj3621Sightseeing Cows(01分数规划+spfa判环)

    传送门 01分数规划板题啊. 发现就是一个最优比率环. 这个直接二分+spfa判负环就行了. 代码: #include<iostream> #include<cstdio> # ...

随机推荐

  1. python中使用空格还是使用 Tab键缩进的建议

    对于程序员来说,其实Tab和空格远远不只是“立场”问题那么简单. 在不同的编辑器里tab的长度可能不一致,所以在一个编辑器里用tab设置缩进后,在其它编辑器里看可能缩进就乱了.空格不会出现这个问题,因 ...

  2. python 迭代器 和生成器

    迭代器 # 双下方法 # print([1].__add__([2])) # print([1]+[2]) # 迭代器 # l = [1,2,3] # 索引 # 循环 for # for i in l ...

  3. GDOI DAY1游记

    今天,是本蒟蒻的第一次参加GDOI,真激动! 今天,是GDOI第一天,昨天熬夜打代码,今天早上状态十分不好,于是... 进入了考场,叫我们自由打一会代码,于是...打了一坨AC机,重要的是错了(额.. ...

  4. vue---day01

    1.let和const var 全局作用域和函数作用域 存在变量提升 其实是个bug 可以重复声明 let 块级作用域 不存在变量提升 不能重复声明 const 常量 和let一样还有另外两个 定义的 ...

  5. 动态规划----FatMouse’s Speed(HDU 1160)

    参考:https://blog.csdn.net/u012655441/article/details/64920825 https://blog.csdn.net/wy19910326/articl ...

  6. 使用localStorage,sessionStorage,cookie等存储

    Web 存储 API 提供了 sessionStorage (会话存储) 和 localStorage(本地存储)两个存储对象来对网页的数据进行添加.删除.修改.查询操作. 特点: localStor ...

  7. MySQL共享表空间扩容

    一.什么是共享表空间和独占表空间 共享表空间以及独占表空间都是针对数据的存储方式而言的. 共享表空间: 某一个数据库的所有的表数据,索引文件全部放在一个文件中,默认这个共享表空间的文件路径在data目 ...

  8. 用Kettle的一套流程完成对整个数据库迁移 费元星

    原地址 :http://ainidehsj.iteye.com/blog/1735434 需求: 1.你是否遇到了需要将mysql数据库中的所有表与数据迁移到Oracle. 2.你是否还在使用kett ...

  9. 【C#】 语法糖

    [C#] 语法糖 一, 扩展方法 1. 对某个类功能上的扩展 2. 特点: 使用方便,可以在不修改原代码的基础上进行扩展. 参照 linq,linq 就是一系列的扩展方法 3. 语法: 非泛型静态类, ...

  10. Git初步

    在多人参与开发的项目中,版本控制工具是必须的,网上有很多不错的教程,能简单使用就ok了,粘几篇教程,方便学习 首先我们要了解一些基本的概念,此处简单描述一下 (1)集中式版本控制系统: CVS.SVN ...