bzoj3774 最优选择
题目描述:
小N手上有一个N*M的方格图,控制某一个点要付出Aij的代价,然后某个点如果被控制了,或者他周围的所有点(上下左右)都被控制了,那么他就算是被选择了的。一个点如果被选择了,那么可以得到Bij的回报,现在请你帮小N选一个最优的方案,使得回报-代价尽可能大。
题解:
最开始以为是最大权闭合子图裸题,后来发现少了点什么……
一般的图是正权->负权,但是这道题是负权->正权。
于是考虑拆点+最小割。
先假设手里拿着有所有的价值,即$\sum(b)$
对于一个点有三种情况:
1.占领这个点,此时代价为$a$;
2.不占领这个点,但是上下左右的某一个格子被占领了,此时代价为$0$;
2.不占领这个点,而且上下左右都是空的,此时代价为$b$;
我们可以先将棋盘黑白染色,然后建图。
重点是怎么建图。
拆点,每个点拆出的$x,y$之间连一条容量为$b$的边,源点向黑点的$x$连容量为$a$的边,白点的$y$向汇点连一条容量为$a$的边。
黑$x$向附近的白$x$连容量为$inf$的边,$y$同理。
意思是强迫割掉$a$,$b$或相邻点的$a$。
代码:
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = ;
const int inf = 0x3f3f3f3f;
template<typename T>
inline void read(T&x)
{
T f = ,c = ;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){c=c*+ch-'';ch=getchar();}
x = f*c;
}
int n,m,hed[N],cnt=-,S=,T,cur[N];
int dx[]={-,,,};
int dy[]={,,-,};
bool check(int x,int y){return x>=&&y>=&&x<=n&&y<=m;}
int _id(int x,int y){return (x-)*m+y;}
ll ans;
struct EG
{
int to,nxt;
ll w;
}e[*N];
void ae(int f,int t,ll w)
{
e[++cnt].to = t;
e[cnt].nxt = hed[f];
e[cnt].w = w;
hed[f] = cnt;
}
void AE(int f,int t,ll w)
{
ae(f,t,w);
ae(t,f,);
}
int dep[N];
bool vis[N];
bool bfs()
{
memset(dep,0x3f,sizeof(dep));
memcpy(cur,hed,sizeof(cur));
queue<int>q;
dep[]=,vis[]=;q.push();
while(!q.empty())
{
int u = q.front();
q.pop();
for(int j=hed[u];~j;j=e[j].nxt)
{
int to = e[j].to;
if(e[j].w&&dep[to]>dep[u]+)
{
dep[to]=dep[u]+;
if(!vis[to])vis[to]=,q.push(to);
}
}
vis[u]=;
}
return dep[T]!=inf;
}
ll dfs(int u,ll lim)
{
if(u==T||!lim)return lim;
ll fl=,f;
for(int j=cur[u];~j;j=e[j].nxt)
{
cur[u]=j;
int to = e[j].to;
if(dep[to]==dep[u]+&&(f=dfs(to,min(lim,e[j].w))))
{
fl+=f,lim-=f;
e[j].w-=f,e[j^].w+=f;
if(!lim)break;
}
}
return fl;
}
ll dinic()
{
ll ret=;
while(bfs())
ret+=dfs(S,inf);
return ret;
}
int main()
{
read(n),read(m);
if(n==&&m==)
{
int a,b;
read(a),read(b);
if(b>a)ans=b-a;
printf("%lld\n",ans);
return ;
}
memset(hed,-,sizeof(hed));
for(int i=;i<=n;i++)
for(int a,j=;j<=m;j++)
{
read(a);
if((i+j)&)AE(S,_id(i,j)<<,a);
else AE(_id(i,j)<<|,T,a);
}
for(int i=;i<=n;i++)
for(int b,j=;j<=m;j++)
{
read(b);ans+=b;
int u = _id(i,j);
AE(u<<,u<<|,b);
if((i+j)&)
{
for(int x,y,o=;o<;o++)
{
x = dx[o]+i,y = dy[o]+j;
if(check(x,y))
{
int t = _id(x,y);
AE(u<<,t<<,inf);
AE(u<<|,t<<|,inf);
}
}
}
}
printf("%lld\n",ans-dinic());
return ;
}
bzoj3774 最优选择的更多相关文章
- 【BZOJ3774】最优选择 最小割
[BZOJ3774]最优选择 Description 小N手上有一个N*M的方格图,控制某一个点要付出Aij的代价,然后某个点如果被控制了,或者他周围的所有点(上下左右)都被控制了,那么他就算是被选择 ...
- BZOJ 3774: 最优选择( 最小割 )
最小割...二分染色然后把颜色不同的点的源汇反过来..然后就可以做了. 某个点(x,y): S->Id(x,y)(回报), Id(x,y)->T(代价), Id(i,j)&& ...
- MySQL数据类型的最优选择
MySQL数据类型的最优选择 慎重选择数据类型很重要.为啥哩?可以提高性能.原理如下: ● 存储(内存.磁盘).从而节省I/O(检索相同数据情况下) ● 计算.进而 ...
- 【bzoj3774】最优选择 网络流最小割
题目描述 小N手上有一个N*M的方格图,控制某一个点要付出Aij的代价,然后某个点如果被控制了,或者他周围的所有点(上下左右)都被控制了,那么他就算是被选择了的.一个点如果被选择了,那么可以得到Bij ...
- DQN(Deep Q-learning)入门教程(二)之最优选择
在上一篇博客:DQN(Deep Q-learning)入门教程(一)之强化学习介绍中有三个很重要的函数: 策略:\(\pi(a|s) = P(A_t=a | S_t=s)\) 状态价值函数:\(v_\ ...
- 建站服务器的最优选择之Windows Or Linux
转载于:http://www.0553114.com/news/detail-702287.html 不管是个人建站,还是中小型企业建站,选择一款合适的主机是站长朋友们共同的心愿.主机是选择Windo ...
- [BZOJ 3774] 最优选择 【最小割】
题目链接:BZOJ - 3774 题目分析 此题与“文理分科”那道题目有些类似.都是使用最小割来求解,先加上可能获得的权值,在减掉必须舍弃的权值(最小割). 文理分科是规定每个人和 S 连就是选文,和 ...
- BZOJ 3774 最优选择 (最小割+二分图)
题面传送门 题目大意:给你一个网格图,每个格子都有$a_{ij}$的代价和$b_{ij}$的回报,对于格子$ij$,想获得$b_{ij}$的回报,要么付出$a_{ij}$的代价,要么$ij$周围四联通 ...
- ArrayList、HashTable、List、Dictionary的演化及如何选择使用
在C#中,数组由于是固定长度的,所以常常不能满足我们开发的需求. 由于这种限制不方便,所以出现了ArrayList. ArrayList.List<T> ArrayList是可变长数组,你 ...
随机推荐
- Codeforces Round #422 (Div. 2) C. Hacker, pack your bags!(更新数组)
传送门 题意 给出n个区间[l,r]及花费\(cost_i\),找两个区间满足 1.区间和为指定值x 2.花费最小 分析 先用vector记录(l,r,cost)和(r,l,cost),按l排序,再设 ...
- POJ1466/HDOJ1068 谈谈二分匹配的时间复杂度
题意: n个学生编号是0-n-1,然后给出他们这些人和一些人的关系. 要你找出最大的人数,要求这些人之间没关系. 咳咳,题目中没说性别的关系TVT 思路: 很明显是一个匹配算法,但是我们得搞出一个二分 ...
- IO流案例:1.复制多级文件夹 2.删除多级文件夹
package copy; /* 需求:复制多级文件夹 复制d:\\itcast(包含文件和子文件夹)到模块目录下 分析: d:\\itcast a.txt b.txt javaweb a.xml b ...
- Python基础知识(1)
Python 3 1:print:输出信息 例子: ( 所有的标点符号都要是英文状态下输入,要不然会报错) print(“hello world”) 2:注意 : python 和 pyth ...
- 接口测试postman和Jmeter
接口测试属于功能测试的范畴,一般来说分为两种,一种是程序内部的接口,一种是系统对外的接口. postman测试接口 1. get请求: (1) 直接在浏览器中输入接口地址+?+参数 (2)使用post ...
- HDU - 6058 Kanade's sum
Bryce1010模板 http://acm.hdu.edu.cn/showproblem.php?pid=6058 /* 思路是:找出每个x为第k大的区间个数有多少 用pos[i]保存当前x的位置, ...
- 牛客练习赛25-A-因数个数和
题目描述 q次询问,每次给一个x,问1到x的因数个数的和. 输入描述: 第一行一个正整数q:接下来q行,每行一个正整数x 输出描述: 共q行,每行一个正整数表示答案 输入 4 1 2 3 10 输出 ...
- P1984 [SDOI2008]烧水问题
题目描述 把总质量为1kg的水分装在n个杯子里,每杯水的质量均为(1/n)kg,初始温度均为0℃.现需要把每一杯水都烧开.我们可以对任意一杯水进行加热.把一杯水的温度升高t℃所需的能量为(4200*t ...
- oracle PL、SQL(概念)
一.PL/SQL简介. Oracle PL/SQL语言(Procedural Language/SQL)是结合了结构化查询和Oracle自身过程控制为一体的强大语言,PL/SQL不但支持更多的数据类型 ...
- Quartz使用二 通过属性传递数据
上一篇介绍了通过context.getJobDetail().getJobDataMap()方式获取传递的数据,其实可以通过定义属性来传递参数 package org.tonny.quartz; im ...