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是可变长数组,你 ...
随机推荐
- E20170503-hm
leading edge 前沿 trailing edge 后缘 trail v跟踪 top edge 顶边 bottom edge 底边 intrinsic adj 固有的 intrinsi ...
- 洛谷 - P2055 - 假期的宿舍 - 最大流
https://www.luogu.org/problemnew/show/P2055 这是一个错误的示范. 一开始觉得就找一条路从外校同学连到本校同学然后最终从周末回家的同学流出,每个人睡后一个人的 ...
- hdoj1024【DP.最 大 m 字 段 和】(写完我都怕。。。不忍直视。。)
弱弱上路,看了好多题解....[A的] 题意就是求最大m子段和. 我们先用a[1e6+7]存入数据: 定义:DP[ i , j ] 为前 j 个元素的 i 个子段的最大和,且第 i 个子段中包含了元素 ...
- hdoj1272 小希的迷宫
并查集 = =.一开始判断连通,没有判断环,后来判断了环,没有判断连通... 还有就是一开始是0 0,也是Yes,有道理么?我不是很懂.. #include <iostream> #inc ...
- P5166 xtq的口令
传送门 这题要是搞懂在干什么其实不难(虽然某个花了几个小时才搞明白的家伙似乎没资格这么说--) 假设所有人都没有听到老师的命令,我们从左到右考虑,对于当前的人,如果它没有观察者,那么肯定要让它听到老师 ...
- UIImageView 使图片圆形的方法
UIImageView 圆形的两种方法 1.cornerRadius (tableView,collectionView尽量避免使用,影响性能) //想要圆角 cornerRadius必须是 imag ...
- vs2010中的ADO控件及绑定控件
要在项目中添加某一个ActiveX控件,则该ActiveX控件必须要注册.由于VS2010中,并没有自动注册ADO及ADO数据绑定控件(Microsoft ADO Data Control,Micro ...
- Java | 技术应用 | 利用Jsoup处理页面
根据微信公众号的推文链接地址,对文章内容进行爬取,利用jsoup解析文章源代码,加上结合xpth提取文文章信息, 利用正则表达式读取文章发表时间. Jsoup <!-- jsoup HTML p ...
- git部分指令
git stash #会把所有未提交的修改(包括暂存的和非暂存的)都保存起来,用于后续恢复当前工作目录 git stach pop #恢复之前缓存的工作目录 切换分支: git checkout de ...
- 用 Fleck 实现 websocket 通信
<html lang="en"> <head> <meta charset="utf-8"> <title>rf ...