bzoj2668
来源:互联网 发布:端口聚合是什么意思 编辑:程序博客网 时间:2024/05/19 17:49
Description
有一个n行m列的黑白棋盘,你每次可以交换两个相邻格子(相邻是指有公共边或公共顶点)中的棋子,最终达到目标状态。要求第i行第j列的格子只能参与mi,j次交换。
Input
第一行包含两个整数n,m(1<=n, m<=20)。以下n行为初始状态,每行为一个包含m个字符的01串,其中0表示黑色棋子,1表示白色棋子。以下n行为目标状态,格式同初始状态。以下n行每行为一个包含m个0~9数字的字符串,表示每个格子参与交换的次数上限。
Output
输出仅一行,为最小交换总次数。如果无解,输出-1。
Sample Input
3 3
110
000
001
000
110
100
222
222
222
110
000
001
000
110
100
222
222
222
Sample Output
4
网络流
明显格子等价于可以互相穿过,棋子是一样的
原本就在位置上的棋子我们没必要移
program bzoj2668;const zl:array [1..8,1..2] of longint=((1,0),(-1,0),(0,1),(0,-1),(1,1),(1,-1),(-1,1),(-1,-1));vartot,u,v,x,y,count,ans,n,m,i,j,k:longint; lim:array [0..21,0..21] of longint; a,b:array [0..21,0..21] of char; last,dis,root:array [0..801] of longint; dl,point,next,cost,flow:array [0..100001] of longint; ch:char;function anti (now:longint):longint;inline;begin if now and 1 = 1 then exit(now+1) else exit(now-1);end;procedure connect (u,v,f,c:longint);inline;begin inc(tot); point[tot]:=v; flow[tot]:=f; cost[tot]:=c; next[tot]:=root[u]; root[u]:=tot;end;procedure mcmf;begin repeat fillchar(dis,sizeof(dis),63); tot:=0; dl[0]:=0; dis[0]:=0; i:=0; while i<=tot do begin k:=root[dl[i]]; while k<>0 do begin if (flow[k]>0)and(dis[point[k]]>dis[dl[i]]+cost[k]) then begin last[point[k]]:=k; dis[point[k]]:=dis[dl[i]]+cost[k]; inc(tot); dl[tot]:=point[k]; end; k:=next[k]; end; inc(i); end; if dis[801]>1000000 then break; dec(count); ans:=ans+dis[801]; i:=801; while i<>0 do begin dec(flow[last[i]]); inc(flow[anti(last[i])]); i:=point[anti(last[i])]; end; until false;end;begin readln(n,m); count:=0; for i:=1 to n do begin for j:=1 to m do begin read(a[i,j]); if a[i,j]='1' then inc(count); end; readln; end; k:=0; for i:=1 to n do begin for j:=1 to m do begin read(b[i,j]); if b[i,j]='1' then inc(k); end; readln; end; if count<>k then begin writeln(-1); exit; end; for i:=1 to n do begin for j:=1 to m do begin read(ch); lim[i,j]:=ord(ch)-48; end; readln; end; for i:=1 to n do for j:=1 to m do if (a[i,j]='1')and(b[i,j]='1') then begin dec(count); k:=i*m-m+j; connect(k*2-1,k*2,lim[i,j] div 2,0); connect(k*2,k*2-1,0,0); end else if (a[i,j]='1')or(b[i,j]='1') then begin k:=i*m-m+j; if lim[i,j]=0 then begin writeln(-1); exit; end; connect(k*2-1,k*2,(lim[i,j]-1) div 2 + 1,0); connect(k*2,k*2-1,0,0); if a[i,j]='1' then begin connect(0,k*2-1,1,0); connect(k*2-1,0,0,0); end; if b[i,j]='1' then begin connect(k*2,801,1,0); connect(801,k*2,0,0); end; end else begin k:=i*m-m+j; connect(k*2-1,k*2,lim[i,j] div 2,0); connect(k*2,k*2-1,0,0); end; for i:=1 to n do for j:=1 to m do for k:=1 to 8 do begin x:=i+zl[k,1]; y:=j+zl[k,2]; if (x<1)or(x>n)or(y<1)or(y>m) then continue; u:=i*m-m+j; v:=x*m-m+y; connect(u*2,v*2-1,maxlongint div 10,1); connect(v*2-1,u*2,0,-1); end; mcmf; if count<>0 then begin writeln(-1); exit; end; writeln(ans);end.
- bzoj2668
- bzoj2668 [cqoi2012]交换棋子
- bzoj2668: [cqoi2012]交换棋子
- bzoj2668 [cqoi2012]交换棋子
- BZOJ2668: [cqoi2012]交换棋子 费用流
- 【BZOJ2668】【cqoi2012】交换棋子 费用流
- 【费用流模型】BZOJ2668 UVA1317 UVA1486 UVA1104
- 【费用流模型】BZOJ2668 UVA1317 UVA1486 UVA1104
- 【bzoj2668】【cqoi2012】【交换棋子】【费用流】
- PHP的C扩展 makefile的修改
- jsp 成员声明和局部生明
- Objective-C数组
- Top 30 Django Tutorials and Articles
- zencart数据库操作函数
- bzoj2668
- cisco command 详解
- .net mvc3 站点配置404错误自定义页面,返回404状态码。
- assumption versus belief
- Java学习第十二天
- memcache的启动参数
- ios上的绘制优化
- js parseInt 用法
- PowerDesigner Name/Code自动调整