对于这种题很容易看出是费用流吧……

但这道题不容易建模;

首先是怎么表示目标状态和其实状态,看起来有黑有白很复杂

但实际上,不难发现,白色格子没什么用,起决定作用的是黑格子

也就是我们可以把问题简化:我们怎么把开始的黑格子移到目标位置

但这个移动不是一般的移动;

在一条路径中,不难发现,起始两点是只要交换一次,其他路径上个点都是要交换2次

由于题目给出的限制是点的交换次数限制c,所以不难想到要拆点

但是平常的拆两点好像无法表示这个特征,

于是我们就拆成3个点……

p1--->p0--->p2

p1表示交换进来,p2表示交换出去;

所以不难得出:

对于每个点,如果它是原图中的黑点,连边<p1,p0,c/2,0>,<p0,p2,(c+1)/2,0>,<s,p0,1,0>;

如果它是新图中的黑点,连边<p1,p0,(c+1)/2>,<p0,p2,c/2,0>,<p0,t,1,0>;

注意存在有的点在新图原图都是黑点的情况(在这里WA了一次)

如果它在两个图中都是白点,那么连边<p1,p0,c/2,0>,<p0,p2,c/2,0>

最后对于原图中任意可达两点,连边<pi2,pj1,inf,1>

注意这道题可以交换对角线,还要判断是否可行,细节挺多

 const dx:array[..] of integer=(-,,,,,-,-,);
      dy:array[..] of integer=(,,,-,,-,,-);
      inf=;
type node=record
       next,point,cost,flow:longint;
     end; var edge:array[..] of node;
    p,pre,cur,d:array[..] of longint;
    v:array[..] of boolean;
    a,b,c:array[..,..] of integer;
    q:array[..] of longint;
    ch,t,n,m,i,j,k,x,y,po,tot,sum,ans,len:longint;
    s:string; procedure add(x,y,f,w:longint);
  begin
    inc(len);
    edge[len].point:=y;
    edge[len].flow:=f;
    edge[len].cost:=w;
    edge[len].next:=p[x];
    p[x]:=len;
  end; function spfa:boolean;
  var i,x,y,f,r:longint;
  begin
    fillchar(v,sizeof(v),false);
    v[]:=true;
    for i:= to t do
      d[i]:=inf;
    d[]:=;
    f:=;
    r:=;
    q[f]:=;
    while f<=r do
    begin
      x:=q[f];
      v[x]:=false;
      i:=p[x];
      while i<>- do
      begin
        y:=edge[i].point;
        if edge[i].flow> then
          if d[y]>d[x]+edge[i].cost then
          begin
            d[y]:=d[x]+edge[i].cost;
            pre[y]:=x;
            cur[y]:=i;
            if not v[y] then
            begin
              inc(r);
              q[r]:=y;
              v[y]:=true;
            end;
          end;
        i:=edge[i].next;
      end;
      inc(f);
    end;
    if d[t]=inf then exit(false) else exit(true);
  end; procedure mincost;
  var i,j,neck:longint;
  begin
    while spfa do
    begin
      i:=t;
      neck:=inf;
      while i<> do
      begin
        j:=cur[i];
        if neck>edge[j].flow then neck:=edge[j].flow;
        i:=pre[i];
      end;
      i:=t;
      while i<> do
      begin
        j:=cur[i];
        dec(edge[j].flow,neck);
        inc(edge[j xor ].flow,neck);
        i:=pre[i];
      end;
      ans:=ans+d[t]*neck;
      dec(ch,neck);
      if ch= then break;
    end;
  end; begin
  readln(n,m);
  len:=-;
  fillchar(p,sizeof(p),);
  t:=*n*m+;
  for i:= to n do
  begin
    readln(s);
    for j:= to m do
    begin
      a[i,j]:=ord(s[j])-;
      tot:=tot+a[i,j];
    end;
  end;
  for i:= to n do
  begin
    readln(s);
    for j:= to m do
    begin
      b[i,j]:=ord(s[j])-;
      sum:=sum+b[i,j];
    end;
  end;
  for i:= to n do
  begin
    readln(s);
    for j:= to m do
      c[i,j]:=ord(s[j])-;
  end;
  if sum<>tot then
  begin
    writeln(-);
    halt;
  end
  else ch:=sum;
  sum:=n*m;
  for i:= to n do
  begin
    for j:= to m do
    begin
      x:=(i-)*m+j;
      if a[i,j]= then
      begin
        add(x+sum,x,c[i,j] shr ,);
        add(x,x+sum,,);
        add(x,x+*sum,(c[i,j]+) shr ,);
        add(x+*sum,x,,);
        add(,x,,);
        add(x,,,);
        if b[i,j]= then    //细节
        begin
          add(x,t,,);
          add(t,x,,);
        end;
      end
      else if b[i,j]= then
      begin
        add(x+sum,x,(c[i,j]+) shr ,);
        add(x,x+sum,,);
        add(x,x+*sum,c[i,j] shr ,);
        add(x+*sum,x,,);
        add(x,t,,);
        add(t,x,,);
      end
      else if (a[i,j]+b[i,j]=) then
      begin
        add(x+sum,x,c[i,j] shr ,);
        add(x,x+sum,,);
        add(x,x+*sum,c[i,j] shr ,);
        add(x+*sum,x,,);
      end;
    end;
  end;   for i:= to n do
    for j:= to m do
    begin
      po:=(i-)*m+j;
      for k:= to do
      begin
        x:=i+dx[k];
        y:=j+dy[k];
        if (x<=n) and (y<=m) and (x>) and (y>) then
        begin
          tot:=(x-)*m+y;
          add(po+*sum,tot+sum,inf,);
          add(tot+sum,po+*sum,,-);
        end;
      end;
    end;
  mincost;
  if ch<> then writeln(-) else writeln(ans);
end.

bzoj2668的更多相关文章

  1. 【BZOJ2668】[cqoi2012]交换棋子 费用流

    [BZOJ2668][cqoi2012]交换棋子 Description 有一个n行m列的黑白棋盘,你每次可以交换两个相邻格子(相邻是指有公共边或公共顶点)中的棋子,最终达到目标状态.要求第i行第j列 ...

  2. BZOJ2668 [cqoi2012]交换棋子 【费用流】

    题目链接 BZOJ2668 题解 容易想到由\(S\)向初始的黑点连边,由终态的黑点向\(T\)连边,然后相邻的点间连边 但是这样满足不了交换次数的限制,也无法计算答案 考虑如何满足一个点的交换次数限 ...

  3. 【BZOJ-2668】交换棋子 最小费用最大流

    2668: [cqoi2012]交换棋子 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1055  Solved: 388[Submit][Status ...

  4. BZOJ2668: [cqoi2012]交换棋子

    题解: 可以戳这里:http://www.cnblogs.com/zig-zag/archive/2013/04/21/3033485.html 其实自己yy一下就知道这样建图的正确性了. 感觉太神奇 ...

  5. BZOJ2668:[CQOI2012]交换棋子——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=2668 https://www.luogu.org/problemnew/show/P3159#sub ...

  6. BZOJ2668:[CQOI2012]交换棋子(费用流)

    题目描述 有一个n行m列的黑白棋盘,你每次可以交换两个相邻格子(相邻是指有公共边或公共顶点)中的棋子,最终达到目标状态.要求第i行第j列的格子只能参与mi,j次交换. 输入输出格式 输入格式: 第一行 ...

  7. [CQOI2012][bzoj2668] 交换棋子 [费用流]

    题面 传送门 思路 抖机灵 一开始看到这题我以为是棋盘模型-_-|| 然而现实是骨感的 后来我尝试使用插头dp来交换,然后又惨死 最后我不得不把目光转向那个总能化腐朽为神奇的算法:网络流 思维 我们要 ...

  8. BZOJ2668: [cqoi2012]交换棋子(费用流)

    Description 有一个n行m列的黑白棋盘,你每次可以交换两个相邻格子(相邻是指有公共边或公共顶点)中的棋子,最终达到目标状态.要求第i行第j列的格子只能参与mi,j次交换. Input 第一行 ...

  9. [bzoj2668] [洛谷P3159] [cqoi2012] 交换棋子

    Description 有一个n行m列的黑白棋盘,你每次可以交换两个相邻格子(相邻是指有公共边或公共顶点)中的棋子,最终达到目标状态.要求第i行第j列的格子只能参与mi,j次交换. Input 第一行 ...

随机推荐

  1. 正则表达式模块re

    正则表达式通过特定的式子匹配某种类型的字符串.对字符串进行匹配验证或者从大量的字符串里提取出特定的信息. 正则表达式包含普通字符和特殊字符.大部分的普通字符如‘A’或‘0’可以简单的来匹配自己.如te ...

  2. win32进程间通讯--共享内存

    小白一枚,如有不对,请各位大神多多指教! 最近看了看win32进程间通讯.简单写了写利用共享内存实现进程间通讯 使用共享内存实现进程间通讯: 1.在WM_CREATE消息下创建文件映射内核对象 hMa ...

  3. oracle 表空间、用户名 相关语句

    一.oracle查询表空间文件所在路径 select * from dba_data_files t  where t.tablespace_name='FLW' 二.计算出表空间各相关数据 SELE ...

  4. Angularjs 通过WebApi 下载excel

    如果想知道 AngularJs 通过WebAPI 下载Excel.请看下文,这里仅提供了一种方案. 服务器端代码如下: protected HttpResponseMessage GenereateE ...

  5. iOS的layoutSubviews和drawRect方法何时调用

    layoutSubviews在以下情况下会被调用: 1.init初始化不会触发layoutSubviews.2.addSubview会触发layoutSubviews.3.设置view的Frame会触 ...

  6. HighCharts 根据spline-plot-bands图,定制自己的图(区间里显示多个数据)

    公司项目里有这样一个需求,根据数据绘图,但是数据很多,不可能每个点每个点的去画,这样显示的数据太密集非常的难看(更显得技术不专业),如图: 所以我和项目经理商量如何显示这个图形,按照他的意思是,按照范 ...

  7. XSS与CSRF两种跨站攻击比较

    XSS:跨站脚本(Cross-site scripting) CSRF:跨站请求伪造(Cross-site request forgery) 在那个年代,大家一般用拼接字符串的方式来构造动态SQL 语 ...

  8. PHP5 session 详解

    http协议是WEB服务器与客户端(浏览器)相互通信的协议,它是一种无状态协议.所谓无状态,指的是不会维护http请求数据,http请求是独立的,非持久的.而越来越复杂的WEB应用,需要保存一些用户状 ...

  9. 算法导论_ch2

    Ch2算法基础 whowhoha@outlook.com 2.1 插入排序 输入:n个数的一个序列〈a1,a2,…,an〉. 输出:输入序列的一个排列〈a′1,a′2,…,a′n〉,满足a′1≤a′2 ...

  10. 初试docker以及搭建mysql on docker

    前一阵阅读了google的borg论文,在最后的related works和总结中发现了kubernetes.从论文中了解的kubernetes这个东西很有意思,按照论文所说,它的实现有希望解决an ...