【BZOJ3232】圈地游戏 分数规划+最小割
【BZOJ3232】圈地游戏
Description
Input
Output
Sample Input
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
HINT

题解:感觉分数规划的题经常和网络流搭配,但建图还是我的弱项啊~
先二分答案mid,将所有边的权值变成(mid*边权),然后相当于跑一个点权为正,边权为负的最大权闭合图,然后思考怎么建图
1.从S向所有点连一条容量为点权的边,这是由最大权闭合图的思想得到
2.从所有点向相邻的点连一条容量为(mid*边权)的边(具体地说,是两条有向边),这个在两个点都选或都不选的时候没什么用,但是如果一个选另一个不选,那么就相当于要付出这条边边权的代价
3.从所有边界上的点向T连一条容量为(mid*边权)的边,这个可以理解为在网格外面还有一圈的点,这些点必须不选,也就相当于这些点可以和T看成一个点。那么如果选了边界上的点,必须付出这些边界上的边权 的代价。
这样最优代价和就变成了(所有正权和-最小割),如果是正值,就调整l,否则调整r
如果你不理解这样建图的可行性,可以yy一下:
如果我们选出了这样一些点,那么他们和相邻的不选的点(包括网格外的点)都要用边隔开,也就是说我们要付出这些边的代价,(2)(3)中连的边可以满足这个要求;此时,其余的点都不能选,意味着他们都要和S隔开,意味着我们要付出这些点点权的代价,(1)中连的边可以满足这些要求;又因为所有不选的点一定会间接的和网格外的点相连,那么它们自然地被划分到了T集合中,当然,选的点也已经被划分到了S集合中,此时我们已经成功的将所有代价都 割 掉了
如果还感觉说的不清楚的话可能是我自己理解的也不够 细 吧~
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#define eps 1e-6
#define P(A,B) ((A-1)*m+B)
using namespace std;
int n,m,cnt,S,T;
int d[3000],to[500000],next[500000],head[3000];
int map[60][60],e1[60][60],e2[60][60];
double val[500000],ans,tot;
queue<int> q;
double dfs(int x,double mf)
{
if(x==T) return mf;
int i;
double temp=mf,k;
for(i=head[x];i!=-1;i=next[i])
{
if(val[i]>eps&&d[to[i]]==d[x]+1)
{
k=dfs(to[i],min(temp,val[i]));
if(k<eps) d[to[i]]=0;
val[i]-=k,val[i^1]+=k,temp-=k;
if(temp<eps) break;
}
}
return mf-temp;
}
int bfs()
{
while(!q.empty()) q.pop();
memset(d,0,sizeof(d));
int i,u;
q.push(S),d[S]=1;
while(!q.empty())
{
u=q.front(),q.pop();
for(i=head[u];i!=-1;i=next[i])
{
if(!d[to[i]]&&val[i]>eps)
{
d[to[i]]=d[u]+1;
if(to[i]==T) return 1;
q.push(to[i]);
}
}
}
return 0;
}
void add(int a,int b,double c)
{
to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++;
to[cnt]=a,val[cnt]=0,next[cnt]=head[b],head[b]=cnt++;
}
bool check(double sta)
{
int i,j;
memset(head,-1,sizeof(head));
cnt=0;
S=0,T=n*m+1;
ans=0.0;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
add(0,P(i,j),1.0*map[i][j]);
for(i=1;i<n;i++)
for(j=1;j<=m;j++)
add(P(i,j),P(i+1,j),sta*e1[i][j]),add(P(i+1,j),P(i,j),sta*e1[i][j]);
for(i=1;i<=n;i++)
for(j=1;j<m;j++)
add(P(i,j),P(i,j+1),sta*e2[i][j]),add(P(i,j+1),P(i,j),sta*e2[i][j]);
for(i=1;i<=m;i++) add(P(1,i),T,sta*e1[0][i]),add(P(n,i),T,sta*e1[n][i]);
for(i=1;i<=n;i++) add(P(i,1),T,sta*e2[i][0]),add(P(i,m),T,sta*e2[i][m]);
while(bfs()) ans+=dfs(0,99999999.999999);
return tot-ans>eps;
}
int main()
{
scanf("%d%d",&n,&m);
int i,j;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
scanf("%d",&map[i][j]),tot+=1.0*map[i][j];
for(i=0;i<=n;i++)
for(j=1;j<=m;j++)
scanf("%d",&e1[i][j]);
for(i=1;i<=n;i++)
for(j=0;j<=m;j++)
scanf("%d",&e2[i][j]);
double l=0.0,r=n*m*100.0,mid;
while(r-l>eps)
{
mid=(l+r)*0.5;
if(check(mid)) l=mid;
else r=mid;
}
printf("%.3f",l);
return 0;
}
【BZOJ3232】圈地游戏 分数规划+最小割的更多相关文章
- bzoj 3232: 圈地游戏【分数规划+最小割】
数组开小导致TTTTTLE-- 是分数规划,设sm为所有格子价值和,二分出mid之后,用最小割来判断,也就是判断sm-dinic()>=0 这个最小割比较像最大权闭合子图,建图是s像所有点连流量 ...
- bzoj 3232 圈地游戏 —— 01分数规划+最小割建图(最大权闭合子图)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3232 心烦意乱的时候调这道题真是...越调越气,就这样过了一晚上... 今天再认真看看,找出 ...
- BZOJ 3232: 圈地游戏 分数规划+判负环
3232: 圈地游戏 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 966 Solved: 466[Submit][Status][Discuss] ...
- zoj 2676 Network Wars 0-1分数规划+最小割
题目详解出自 论文 Amber-最小割模型在信息学竞赛中的应用 题目大意: 给出一个带权无向图 G = (V,E), 每条边 e属于E都有一个权值We,求一个割边集C,使得该割边集的平均边权最小,即最 ...
- 【洛谷P2494】 [SDOI2011]保密(分数规划+最小割)
洛谷 题意: 题意好绕好绕...不想写了. 思路: 首先类似于分数规划做法,二分答案得到到每个点的最小危险度. 然后就是在一个二分图中,两边撤掉最少的点(相应代价为上面算出的危险度)及相应边,使得中间 ...
- 洛谷2494 [SDOI2011]保密 (分数规划+最小割)
自闭一早上 分数规划竟然还能被卡精度 首先假设我们已经知道了到每个出入口的时间(代价) 那我们应该怎么算最小的和呢? 一个比较巧妙的想法是,由于题目规定的是二分图. 我们不妨通过最小割的形式. 表示这 ...
- HDU 2676 Network Wars 01分数规划,最小割 难度:4
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1676 对顶点i,j,起点s=1,终点t=n,可以认为题意要求一组01矩阵use ...
- bzoj3232圈地游戏——0/1分数规划+差分建模+判环
Description DZY家的后院有一块地,由N行M列的方格组成,格子内种的菜有一定的价值,并且每一条单位长度的格线有一定的费用. DZY喜欢在地里散步.他总是从任意一个格点出发,沿着格线行走直到 ...
- 【题解】 [HNOI2009] 最小圈 (01分数规划,二分答案,负环)
题目背景 如果你能提供题面或者题意简述,请直接在讨论区发帖,感谢你的贡献. 题目描述 对于一张有向图,要你求图中最小圈的平均值最小是多少,即若一个圈经过k个节点,那么一个圈的平均值为圈上k条边权的和除 ...
随机推荐
- selenium 实现浏览器 前进和后退
#coding=utf-8from selenium import webdriver driver = webdriver.Chrome()driver.get("https://www. ...
- 雅虎天气API调用
雅虎天气API调用: 1.调用方法:http://weather.yahooapis.com/forecastrss?w=2502265&u=c,绿色字体为城市代号,u=c表示取摄氏度. 2. ...
- Java 枚举(enum) 的常见用法和开发规范
JDK1.5引入了新的类型——枚举.在 Java 中它虽然算个“小”功能,却给我的开发带来了“大”方便. 用法一:常量 在JDK1.5 之前,我们定义常量都是: public static final ...
- 自己是个菜鸟 自己查找的简单的适合初学的Makefile
工程中的代码分别存放在add/add_int.c.add/add_float.c.add/add.h.sub/sub_int.c.sub/sub_float.c.sub/sub.h.main.c中. ...
- Android实战简易教程-第二十三枪(基于Baas的用户注冊验证username是否反复功能!)
接上一篇,加入验证用户名是否已经注冊功能! 仅仅须要改动MainActivity.java: package com.example.logintest; import java.util.List; ...
- 每日英语:Risk-Averse Culture Infects U.S. Workers, Entrepreneurs
Americans have long taken pride on their willingness to bet it all on a dream. But that risk-taking ...
- fromdata上传数据
使用formdata上传数据 $(function() { fileStack=[];//总的上传图片栈 //上传事件 $("#uploadBtn").on("click ...
- JS学习笔记(3)--json格式数据的添加,删除及排序方法
这篇文章主要介绍了json格式数据的添加,删除及排序方法,结合实例形式分析了针对一维数组与二维数组的json格式数据进行增加.删除与排序的实现技巧,需要的朋友可以参考下 本文实例讲述了json格式 ...
- Ajax的两个用法
1.实现的效果是:通过一个函数,里面调用Ajax,函数的返回值是Ajax成功调用之后得到的返回值. 用jQuery进行简单的演示: function getRobotInfo(id) { var ip ...
- 微信小程序7 - 页面命名规范
/pages/{module}/{page}/index.js 这个是目录结构 所有单个页面(Page)目录内, 都叫做index,如 index.js index.wxss ,不需要起其他名 ...