BZOJ 2668 [cqoi2012]交换棋子 | 最小费用最大流
传送门
题解
同时分别限制流入和流出次数,所以把一个点拆成三个:入点in(x)、中间点mi(x)、出点ou(x)。
如果一个格子x在初始状态是黑点,则连(S, mi(x), 1, 0)
如果x在目标状态是黑点,则连(mi(x), T, 1, 0)
设x的交换次数限制是w
如果x在两种状态中颜色相同,则连(in(x), mi(x), w / 2, 0), (mi(x), ou(x), w / 2, 0)
如果x只在初始状态为黑色,则连(in(x), mi(x), w / 2, 0), (mi(x), ou(x), (w + 1) / 2, 0)
如果x只在目标状态为黑色,则连(in(x), mi(x), (w + 1) / 2, 0), (mi(x), ou(x), w / 2, 0)
每个点x和相邻的点y(八连通),连(ou(x), in(y), INF, 1)
然后最小费用最大流即可。
#include <queue>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <iostream>
#define space putchar(' ')
#define enter putchar('\n')
typedef long long ll;
using namespace std;
template <class T>
void read(T &x){
char c;
bool op = 0;
while(c = getchar(), c < '0' || c > '9')
if(c == '-') op = 1;
x = c - '0';
while(c = getchar(), c >= '0' && c <= '9')
x = x * 10 + c - '0';
if(op) x = -x;
}
template <class T>
void write(T x){
if(x < 0) putchar('-'), x = -x;
if(x >= 10) write(x / 10);
putchar('0' + x % 10);
}
const int N = 1234, M = 1000005, INF = 0x3f3f3f3f;
const int dx[] = {-1, 1, 0, 0, -1, -1, 1, 1};
const int dy[] = {0, 0, -1, 1, -1, 1, -1, 1};
int n, m, tot, maxflow, mincost, src = 1, des = 2, id[23][23][3], b1, b2;
int ecnt = 1, adj[N], pre[N], dis[N], nxt[M], go[M], cap[M], cost[M];
char st[23][23], ed[23][23], cp[23][23];
void _add(int u, int v, int w, int c){
go[++ecnt] = v;
nxt[ecnt] = adj[u];
adj[u] = ecnt;
cap[ecnt] = w;
cost[ecnt] = c;
}
void add(int u, int v, int w, int c){
_add(u, v, w, c);
_add(v, u, 0, -c);
}
bool spfa(){
queue <int> que;
static bool inq[N] = {0};
for(int i = 1; i <= tot; i++)
dis[i] = INF, pre[i] = 0;
dis[src] = 0, que.push(src), inq[src] = 1;
while(!que.empty()){
int u = que.front();
que.pop(), inq[u] = 0;
for(int e = adj[u], v; e; e = nxt[e]){
if(cap[e] && dis[u] + cost[e] < dis[v = go[e]]){
dis[v] = dis[u] + cost[e], pre[v] = e;
if(!inq[v]) que.push(v), inq[v] = 1;
}
}
}
return dis[des] < INF;
}
void mcmf(){
while(spfa()){
int delta = INF;
for(int e = pre[des]; e; e = pre[go[e ^ 1]])
delta = min(delta, cap[e]);
for(int e = pre[des]; e; e = pre[go[e ^ 1]])
cap[e] -= delta, cap[e ^ 1] += delta;
maxflow += delta;
mincost += delta * dis[des];
}
}
bool legal(int x, int y){
return x > 0 && y > 0 && x <= n && y <= m;
}
int main(){
read(n), read(m), tot = 3 * n * m + 2;
for(int i = 1, cnt = 2; i <= n; i++)
for(int j = 1; j <= m; j++)
id[i][j][0] = ++cnt, id[i][j][1] = ++cnt, id[i][j][2] = ++cnt;
for(int i = 1; i <= n; i++) scanf("%s", st[i] + 1);
for(int i = 1; i <= n; i++) scanf("%s", ed[i] + 1);
for(int i = 1; i <= n; i++) scanf("%s", cp[i] + 1);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++){
int w = cp[i][j] - '0';
if(st[i][j] == '1') b1++, add(src, id[i][j][0], 1, 0);
if(ed[i][j] == '1') b2++, add(id[i][j][0], des, 1, 0);
if(st[i][j] == ed[i][j]){
add(id[i][j][1], id[i][j][0], w / 2, 0);
add(id[i][j][0], id[i][j][2], w / 2, 0);
}
else if(st[i][j] == '1'){
add(id[i][j][1], id[i][j][0], w / 2, 0);
add(id[i][j][0], id[i][j][2], (w + 1) / 2, 0);
}
else if(ed[i][j] == '1'){
add(id[i][j][1], id[i][j][0], (w + 1) / 2, 0);
add(id[i][j][0], id[i][j][2], w / 2, 0);
}
for(int d = 0, x, y; d < 8; d++)
if(legal(x = i + dx[d], y = j + dy[d]))
add(id[i][j][2], id[x][y][1], INF, 1);
}
mcmf();
if(maxflow < max(b1, b2)) puts("-1");
else write(mincost), enter;
return 0;
}
BZOJ 2668 [cqoi2012]交换棋子 | 最小费用最大流的更多相关文章
- BZOJ 2668: [cqoi2012]交换棋子
2668: [cqoi2012]交换棋子 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 1112 Solved: 409[Submit][Status ...
- 【BZOJ-2668】交换棋子 最小费用最大流
2668: [cqoi2012]交换棋子 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 1055 Solved: 388[Submit][Status ...
- BZOJ.2668.[CQOI2012]交换棋子(费用流zkw)
题目链接 首先黑白棋子的交换等价于黑棋子在白格子图上移动,都到达指定位置. 在这假设我们知道这题用网络流做. 那么黑棋到指定位置就是一条路径,考虑怎么用流模拟出这条路径. 我们发现除了路径的起点和终点 ...
- BZOJ 1061 志愿者招募(最小费用最大流)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1061 题意:申奥成功后,布布经过不懈努力,终于 成为奥组委下属公司人力资源部门的主管.布 ...
- bzoj 1070 [SCOI2007]修车(最小费用最大流)
1070: [SCOI2007]修车 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3515 Solved: 1411[Submit][Status] ...
- BZOJ 1221: [HNOI2001] 软件开发(最小费用最大流)
不知道为什么这么慢.... 费用流,拆点.... --------------------------------------------------------------------------- ...
- bzoj 3171: [Tjoi2013]循环格 最小费用最大流
题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=3171 题解: 首先我们很容易发现一个结论: 出现完美循环当且仅当所有点的出入度均为1 所 ...
- bzoj 1070: [SCOI2007]修车【最小费用最大流】
一开始从客人角度想的,怎么建都不对 从一个修车工所接待的所有顾客花费的总时间来看,设一共有x个人,那么第一个修的对总时间的贡献是x*w1,第二个是(x-1)*w2-以此类推.所以把第i个修车工拆成n组 ...
- BZOJ 1449 球队收益(最小费用最大流)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1449 题意: 思路:首先,我们假设后面的M场比赛两方都是输的,即初始时的lose[i]再 ...
随机推荐
- 关于EL表达式中requestScope和param区别
今天演示EL表达式的时候发现自己jsp的基础实在是薄弱,在这个很简单的问题上迷惑了很久. 首先在看遇到的问题: 在浏览器地址输入,表示传入一个参数test,值为123 http://localhost ...
- 关于this指向,翻到的
关于JavaScript函数执行环境的过程,IBM developerworks文档库中的一段描述感觉很不错,摘抄如下: “JavaScript 中的函数既可以被当作普通函数执行,也可以作为对象的方法 ...
- 20155209 林虹宇Exp2 后门原理与实践
Exp2 后门原理与实践 实验内容 一.使用netcat获取主机操作Shell,cron启动 使用netcat获取主机操作Shell Win获得Linux Shell 查看win的ip地址 windo ...
- 20155334 《网络攻防》 Exp9 Web安全基础
<网络攻防> Exp9 Web安全基础 一.实验后回答问题 SQL注入攻击原理,如何防御: 原理: 就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服 ...
- POJ 1789&&2485&&1258&&3026
这个真的太水了——MST专辑. 如果不会MST的两种算法的同学可以出门右转了. 大致讲一下,第一题我是用Prim+堆优化的(毕竟点比较多),后面三题用的是Kruskal(习惯打,而且并查集常数实在小) ...
- 【php增删改查实例】 第二节 - MYSQL环境配置
安装好xampp后,会自带一个mysql,也就是说,正常情况下,你直接这样: 就可以启动mysql了. 如果你了,下面的步骤就别看了哈. if( 启动成功 ){ return; } 如果你的电脑上已经 ...
- 【转载】VS中的路径宏 vc++中OutDir、ProjectDir、SolutionDir各种路径
原文:http://www.cnblogs.com/lidabo/archive/2012/05/29/2524170.html 说明 $(RemoteMachine) 设置为“调试”属性页上“远程计 ...
- Yii2 软删除
什么是软删除 后台操作,删除一条记录,不希望真正的从数据库中删除,用个字段标记一下.比如delete_at.默认0.当执行删除操作,更新delete_at为当前时间戳 这样列表显示的时候只查询dele ...
- Neo4j 第四篇:使用C#更新和查询Neo4j
本文使用的IDE是Visual Studio 2015 ,驱动程序是Neo4j官方的最新版本:Neo4j Driver 1.3.0 ,创建的类库工程(Project)要求安装 .NET Framewo ...
- 重置Oracle配置
经常被ORACLE坑,作为一个只需要开发时候连连ORACLE的程序员,在经历了一次又一次的折腾之后,决定还是把这些琐碎的事情写下来. 经常在虚拟机中使用ORACLE,ORACLE的网络配置有一些变化就 ...