BZOJ 2668 交换棋子(费用流)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2668
题意:有一个n行m列的黑白棋盘,你每次可以交换两个相邻格子中的棋子,最终达到目标状态。要求第i行第j列的格子只能参与m[i,j]次交换。
思路: 我们将1看做要移动的数字,将0看做空白。那么若1在始末状态个数不同则无解;如某个格子始末状态均有1则这个格子的1对结果无影响,可以将其都置为0。将每个格子拆为为个点p0,p1,p2:
(1)若格子初始为1,则连边:<s,p0,1,0>,<p1,p0,m[i][j]/2,0)>,<p0,p2,(m[i][j]+1)/2,0>;
(2)若格子末状态为0,则连边:<p0,t,1,0>,<p1,p0,(m[i][j]+1)/2,0>,<p0,p2,m[i][j]/2,0>;
(3)始末都是空白,则连边:<p1,p0,m[i][j]/2,0>,<p0,p2,m[i][j]/2,0>;
(4)相邻格子x和y连边<px2,py1,INF,0>。
struct node
{
int u,v,next,cost,cap;
};
node edges[N];
int head[N],e;
void add(int u,int v,int cap,int cost)
{
edges[e].u=u;
edges[e].v=v;
edges[e].cap=cap;
edges[e].cost=cost;
edges[e].next=head[u];
head[u]=e++;
}
void Add(int u,int v,int cap,int cost)
{
add(u,v,cap,cost);
add(v,u,0,-cost);
}
int pre[N],F[N],C[N],visit[N];
int SPFA(int s,int t,int n)
{
int i;
for(i=0;i<=n;i++) F[i]=0,C[i]=INF,visit[i]=0;
queue<int> Q;
Q.push(s); F[s]=INF; C[s]=0;
int u,v,cost,cap;
while(!Q.empty())
{
u=Q.front();
Q.pop();
visit[u]=0;
for(i=head[u];i!=-1;i=edges[i].next)
{
if(edges[i].cap>0)
{
v=edges[i].v;
cost=edges[i].cost;
cap=edges[i].cap;
if(C[v]>C[u]+cost)
{
C[v]=C[u]+cost;
F[v]=min(F[u],cap);
pre[v]=i;
if(!visit[v]) visit[v]=1,Q.push(v);
}
}
}
}
return F[t];
}
char a[25][25],b[25][25],c[25][25];
int d[25][25][3];
int dx[]={-1,-1,-1,0,1,1,1,0};
int dy[]={-1,0,1,1,1,0,-1,-1};
int n,m,s,t,cnt;
int ans;
int MCMF(int s,int t,int n)
{
int i,x,temp,M=0;
while(temp=SPFA(s,t,n))
{
M+=temp;
for(i=t;i!=s;i=edges[pre[i]].u)
{
x=pre[i];
ans+=edges[x].cost*temp;
edges[x].cap-=temp;
edges[x^1].cap+=temp;
}
}
return M==cnt;
}
int main()
{
RD(n,m);
int i,j;
FOR1(i,n) RD(a[i]+1);
FOR1(i,n) RD(b[i]+1);
FOR1(i,n) RD(c[i]+1);
int k=0;
FOR1(i,n) FOR1(j,m)
{
a[i][j]-='0';
b[i][j]-='0';
c[i][j]-='0';
d[i][j][0]=++k;
d[i][j][1]=++k;
d[i][j][2]=++k;
if(a[i][j]&&b[i][j]) a[i][j]=0,b[i][j]=0;
}
s=0; t=++k;
clr(head,-1);
cnt=0;
int x,y,p=0;
FOR1(i,n) FOR1(j,m)
{
if(a[i][j])
{
cnt++;
Add(s,d[i][j][0],1,0);
Add(d[i][j][1],d[i][j][0],c[i][j]/2,0);
Add(d[i][j][0],d[i][j][2],(c[i][j]+1)/2,0);
}
else if(b[i][j])
{
p++;
Add(d[i][j][0],t,1,0);
Add(d[i][j][1],d[i][j][0],(c[i][j]+1)/2,0);
Add(d[i][j][0],d[i][j][2],c[i][j]/2,0);
}
else
{
Add(d[i][j][1],d[i][j][0],c[i][j]/2,0);
Add(d[i][j][0],d[i][j][2],c[i][j]/2,0);
}
FOR0(k,8)
{
x=i+dx[k];
y=j+dy[k];
if(x>=1&&x<=n&&y>=1&&y<=m)
{
Add(d[i][j][2],d[x][y][1],INF,1);
}
}
}
if(cnt!=p||!MCMF(s,t,t+1)) puts("-1");
else PR(ans);
}
BZOJ 2668 交换棋子(费用流)的更多相关文章
- 【BZOJ2668】[cqoi2012]交换棋子 费用流
[BZOJ2668][cqoi2012]交换棋子 Description 有一个n行m列的黑白棋盘,你每次可以交换两个相邻格子(相邻是指有公共边或公共顶点)中的棋子,最终达到目标状态.要求第i行第j列 ...
- BZOJ2668: [cqoi2012]交换棋子(费用流)
Description 有一个n行m列的黑白棋盘,你每次可以交换两个相邻格子(相邻是指有公共边或公共顶点)中的棋子,最终达到目标状态.要求第i行第j列的格子只能参与mi,j次交换. Input 第一行 ...
- [BZOJ 2668] 交换棋子
Link: BZOJ 2668 传送门 Solution: 重点在于对于每条转移路径:首尾算一次,中间节点算两次 可以一点拆三点,将原流量拆成入流量和出流量 但其实也可以就拆两点,分前后是否是一首尾点 ...
- BZOJ.2668.[CQOI2012]交换棋子(费用流zkw)
题目链接 首先黑白棋子的交换等价于黑棋子在白格子图上移动,都到达指定位置. 在这假设我们知道这题用网络流做. 那么黑棋到指定位置就是一条路径,考虑怎么用流模拟出这条路径. 我们发现除了路径的起点和终点 ...
- [CQOI2012] 交换棋子 - 费用流
有一个n行m列的黑白棋盘,你每次可以交换两个相邻格子(相邻是指有公共边或公共顶点)中的棋子,最终达到目标状态.要求第i行第j列的格子只能参与mi,j次交换. Solution 一个点拆三份,入点,主点 ...
- [CQOI2012][bzoj2668] 交换棋子 [费用流]
题面 传送门 思路 抖机灵 一开始看到这题我以为是棋盘模型-_-|| 然而现实是骨感的 后来我尝试使用插头dp来交换,然后又惨死 最后我不得不把目光转向那个总能化腐朽为神奇的算法:网络流 思维 我们要 ...
- [bzoj 1449] 球队收益(费用流)
[bzoj 1449] 球队收益(费用流) Description Input Output 一个整数表示联盟里所有球队收益之和的最小值. Sample Input 3 3 1 0 2 1 1 1 1 ...
- BZOJ.2597.[WC2007]剪刀石头布(费用流zkw)
BZOJ 洛谷 \(Description\) 给定一张部分边方向已确定的竞赛图.你需要给剩下的边确定方向,使得图中的三元环数量最多. \(n\leq100\). \(Solution\) 这种选择之 ...
- bzoj 1070: [SCOI2007]修车 费用流
1070: [SCOI2007]修车 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 2785 Solved: 1110[Submit][Status] ...
随机推荐
- SqlServer nvarchar中的中文字符匹配,更改SqlServer实例和数据库排序规则的办法
我们都知道在SqlServer中的nvarchar类型可以完美的存储诸如中文这种unicode字符,但是我们会发现有时候查询语句去查询nvarchar列的时候查不出来. 为什么nvarchar类型有时 ...
- sql2005镜像实现
-- =========================================== -- 无论是主体服务器.镜像服务器, 还是见证服务器 -- 除特别说明外,均需要保证下面的操作 ...
- TortoiseSVN提交文件的时候卡死
提交文件的时候卡死,查找很久,才发现原来是IP被修改了,郁闷
- 文字处理控件TX Text Control X10独家揭秘(一):数据源自动处理
TX Text Control即将发布的X10版本,将升级重点还是放到了其比较优势的流式布局报表设计和生成上.慧都获得了来自其开发商Text Control GmbH公司的一手资料,迫不及待的为大家带 ...
- 160930、Javascript的垃圾回收机制与内存管理
一.垃圾回收机制-GC Javascript具有自动垃圾回收机制(GC:Garbage Collecation),也就是说,执行环境会负责管理代码执行过程中使用的内存. 原理:垃圾收集器会定期(周期性 ...
- bootstrap实现 手机端滑动效果,滑动到下一页,jgestures.js插件
bootstrap能否实现 手机端滑动效果,滑动到下一页 jgestures.js插件可以解决,只需要引入一个JS文件<script src="js/jgestures.min.js& ...
- laravel5.1启动详解
laravel的启动过程 如果没有使用过类似Yii之类的框架,直接去看laravel,会有点一脸迷糊的感觉,起码我是这样的.laravel的启动过程,也是laravel的核心,对这个过程有一个了解,有 ...
- 使用jprofiler8远程监控weblogic的配置方法
jprofiler8的注册码:L-Larry_Lau@163.com#36573-fdkscp15axjj6#25257 未完待续
- 使用Jconsole监控weblogic的配置方法
在项目中发现full gc非常频繁.达到了每分钟13次.我怀疑可能会有内存泄露.于是在晚上找了内存泄露的资料. 内存长期占用并导致系统不稳定一般有两种可能: 1. 对象被大量创建而且被缓存,在旧的对象 ...
- 《深度探索C++对象模型》3
第六章:执行期语意学 全局对象的初始化: 局部静态对象的初始化: 构建对象数组的vec_new()函数: 针对数组的new操作: placement operator new: 反聚合提高效率: 模板 ...