题目描述:

小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 最优选择的更多相关文章

  1. 【BZOJ3774】最优选择 最小割

    [BZOJ3774]最优选择 Description 小N手上有一个N*M的方格图,控制某一个点要付出Aij的代价,然后某个点如果被控制了,或者他周围的所有点(上下左右)都被控制了,那么他就算是被选择 ...

  2. BZOJ 3774: 最优选择( 最小割 )

    最小割...二分染色然后把颜色不同的点的源汇反过来..然后就可以做了. 某个点(x,y): S->Id(x,y)(回报), Id(x,y)->T(代价), Id(i,j)&& ...

  3. MySQL数据类型的最优选择

    MySQL数据类型的最优选择   慎重选择数据类型很重要.为啥哩?可以提高性能.原理如下:            ● 存储(内存.磁盘).从而节省I/O(检索相同数据情况下)      ● 计算.进而 ...

  4. 【bzoj3774】最优选择 网络流最小割

    题目描述 小N手上有一个N*M的方格图,控制某一个点要付出Aij的代价,然后某个点如果被控制了,或者他周围的所有点(上下左右)都被控制了,那么他就算是被选择了的.一个点如果被选择了,那么可以得到Bij ...

  5. DQN(Deep Q-learning)入门教程(二)之最优选择

    在上一篇博客:DQN(Deep Q-learning)入门教程(一)之强化学习介绍中有三个很重要的函数: 策略:\(\pi(a|s) = P(A_t=a | S_t=s)\) 状态价值函数:\(v_\ ...

  6. 建站服务器的最优选择之Windows Or Linux

    转载于:http://www.0553114.com/news/detail-702287.html 不管是个人建站,还是中小型企业建站,选择一款合适的主机是站长朋友们共同的心愿.主机是选择Windo ...

  7. [BZOJ 3774] 最优选择 【最小割】

    题目链接:BZOJ - 3774 题目分析 此题与“文理分科”那道题目有些类似.都是使用最小割来求解,先加上可能获得的权值,在减掉必须舍弃的权值(最小割). 文理分科是规定每个人和 S 连就是选文,和 ...

  8. BZOJ 3774 最优选择 (最小割+二分图)

    题面传送门 题目大意:给你一个网格图,每个格子都有$a_{ij}$的代价和$b_{ij}$的回报,对于格子$ij$,想获得$b_{ij}$的回报,要么付出$a_{ij}$的代价,要么$ij$周围四联通 ...

  9. ArrayList、HashTable、List、Dictionary的演化及如何选择使用

    在C#中,数组由于是固定长度的,所以常常不能满足我们开发的需求. 由于这种限制不方便,所以出现了ArrayList. ArrayList.List<T> ArrayList是可变长数组,你 ...

随机推荐

  1. 一个表的两个字段具有相同的类型。如何仅用SQL语句交换这两列的数据?

    --假设为A B两个字段--查询Select A As B, B As A From TableName --更新Update TableName Set A = B, B = A

  2. 洛谷P3209 [HNOI2010]平面图判定(2-SAT)

    传送门 看到哈密顿回路就被吓傻了……结果没有好好考虑性质…… 首先,平面图有个性质:边数小于等于$3n-6$(我也不知道为啥),边数大于这个的直接pass 然后考虑原图,先把哈密顿回路单独摘出来,就是 ...

  3. 最小生成树Prim算法和Kruskal算法(转)

    (转自这位大佬的博客 http://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html ) Prim算法 1.概览 普里姆算法(Pr ...

  4. python实现汉诺塔(递归)

    def hanoi(n, A, B, C): if n > 0: hanoi(n-1, A, C, B) print("%s->%s" % (A, C)) hanoi( ...

  5. [CQOI2014]通配符匹配

    Description 几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户.最常见的通配符有两个,一个是星号(""'),可以匹配0个及以上的任意字符:另一个 ...

  6. AtCoder Grand Contest 005 C - Tree Restoring

    题目传送门:https://agc005.contest.atcoder.jp/tasks/agc005_c 题目大意: 给定一个长度为\(N\)的整数序列\(A_i\),问能否构造一个\(N\)个节 ...

  7. 回文树1960. Palindromes and Super Abilities

    Bryce1010模板 http://acm.timus.ru/problem.aspx?space=1&num=1960 #include <bits/stdc++.h> usi ...

  8. Broken BST CodeForces - 797D

    Broken BST CodeForces - 797D 题意:给定一棵任意的树,对树上所有结点的权值运行给定的算法(二叉查找树的查找算法)(treenode指根结点),问对于多少个权值这个算法会返回 ...

  9. 双拓扑排序 HDOJ 5098 Smart Software Installer

    题目传送门 /* 双拓扑排序:抄的,以后来补 详细解释:http://blog.csdn.net/u012774187/article/details/40736995 */ #include < ...

  10. 转 ORACLE数据库ORA-00392 log 4 of thread 1 is being cleared, operation not allowed错误

    现象: 数据库在做to-time recovery, 时候,restore and recover 都是正常的,但是最后一步open resetlogs 报错如下 ORA-00392 原因: 因为是在 ...