基本思路是,要让所有黑点都相对应(所以首先判断黑点的个数)。
如果没有交换限制,可以按以下方法建图:源点向所有初始黑点连(1,0)的边,最终黑点向汇点连(1,0)的边,相邻的两点连边(inf,1),最小费用最大流即可。
考虑限制,我们把交换分为两种:(将1)交换进来/交换出去,因此需要两条边(三个点)来限制次数
将一个点拆成三个点,记作i1,i2和i3,设交换次数为s,分类讨论:1.如果初始和结束颜色相同,说明交换了偶数次(因为不会交换相邻两个颜色相同的点),i1连向i2(s/2,0)的边,i2连向i3(s/2,0)的边;2.如果初始是黑色,结束是白色,i1连向i2(s/2,0)的边,i2连向i3((s+1)/2,0)的边;3.如果初始是白色,结束是黑色,i1连向i2((s+1)/2,0)的边,i2连向i3(s/2,0)的边。最后还要将相邻的3向1连一条边,源点和汇点与2相连。

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 2005
4 #define id (n*m+i*m+j+1)
5 #define oo 0x3f3f3f3f
6 struct ji{
7 int nex,to,len,cost;
8 }edge[N*30];
9 queue<int>q;
10 int E,n,m,s1,s2,t,head[N],v[25][25],d[N],vis[N],from[N];
11 char s[N];
12 void add(int x,int y,int z,int w){
13 edge[E].nex=head[x];
14 edge[E].to=y;
15 edge[E].len=z;
16 edge[E].cost=w;
17 head[x]=E++;
18 if (E&1)add(y,x,0,-w);
19 }
20 bool spfa(){
21 memset(d,0x3f,sizeof(d));
22 memset(vis,0,sizeof(vis));
23 q.push(0);
24 d[0]=0;
25 while (!q.empty()){
26 int k=q.front();
27 q.pop();
28 vis[k]=0;
29 for(int i=head[k];i!=-1;i=edge[i].nex){
30 int v=edge[i].to;
31 if ((edge[i].len)&&(d[v]>d[k]+edge[i].cost)){
32 d[v]=d[k]+edge[i].cost;
33 from[v]=i;
34 if (!vis[v]){
35 vis[v]=1;
36 q.push(v);
37 }
38 }
39 }
40 }
41 return d[t]<0x3f3f3f3f;
42 }
43 int dinic(){
44 int len,ans1=0,ans2=0;
45 while (spfa()){
46 len=oo;
47 for(int i=t;i;i=edge[from[i]^1].to)len=min(len,edge[from[i]].len);
48 ans1+=len;
49 ans2+=len*d[t];
50 for(int i=t;i;i=edge[from[i]^1].to){
51 edge[from[i]].len-=len;
52 edge[from[i]^1].len+=len;
53 }
54 }
55 if (ans1<s1)ans2=-1;
56 return ans2;
57 }
58 int main(){
59 scanf("%d%d",&n,&m);
60 memset(head,-1,sizeof(head));
61 t=3*n*m+1;
62 for(int i=0;i<n;i++){
63 scanf("%s",s);
64 for(int j=0;j<m;j++)
65 if (s[j]=='1'){
66 s1++;
67 add(0,id,1,0);
68 v[i][j]++;
69 }
70 }
71 for(int i=0;i<n;i++){
72 scanf("%s",s);
73 for(int j=0;j<m;j++)
74 if (s[j]=='1'){
75 s2++;
76 add(id,t,1,0);
77 v[i][j]+=2;
78 }
79 }
80 for(int i=0;i<n;i++){
81 scanf("%s",s);
82 for(int j=0;j<m;j++){
83 add(id-n*m,id,(s[j]-'0'+(v[i][j]==2))/2,0);
84 add(id,id+n*m,(s[j]-'0'+(v[i][j]==1))/2,0);
85 for(int x=-1;x<2;x++)
86 for(int y=-1;y<2;y++)
87 if (((x)||(y))&&(i+x>-1)&&(i+x<n)&&(j+y>-1)&&(j+y<m))add(id+n*m,id+x*m+y-n*m,oo,1);
88 }
89 }
90 if (s1!=s2)printf("-1");
91 else printf("%d",dinic());
92 }

[bzoj2668]交换棋子的更多相关文章

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

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

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

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

  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. BZOJ 2668: [cqoi2012]交换棋子

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

  6. [cqoi2012]交换棋子

      2668: [cqoi2012]交换棋子 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1334  Solved: 518[Submit][Stat ...

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

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

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

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

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

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

随机推荐

  1. MySQL的详细讲解

    目录 Mysql的架构与历史 MySQL的逻辑架构 更新中---- Mysql的架构与历史 MySQL的逻辑架构 第二层的架构是所有的跨引擎的功能实现的地方,例如:存储,触发器,视图等. 第三层半酣了 ...

  2. SpringBoot+WebSocket实时监控异常

    写在前面 此异常非彼异常,标题所说的异常是业务上的异常. 最近做了一个需求,消防的设备巡检,如果巡检发现异常,通过手机端提交,后台的实时监控页面实时获取到该设备的信息及位置,然后安排员工去处理. 因为 ...

  3. MySQL8 根据某属性查询字段排名由自定义变量到rank()的变动

    在mysql8 之前的版本,因为没有rank()方法的存在,所以在对字段进行排名时,使用的是自定义自变量的方法,比如: select id,name,@rank=@rank+1 as ranks fr ...

  4. FastAPI 学习之路(十)请求体的字段

    系列文章: FastAPI 学习之路(一)fastapi--高性能web开发框架 FastAPI 学习之路(二) FastAPI 学习之路(三) FastAPI 学习之路(四) FastAPI 学习之 ...

  5. HTTP状态码 详细解析汇总

    一.状态码的类别: 类别 原因短语1XX Informational(信息性状态码) 接受的请求正在处理2XX Success(成功状态码) 请求正常处理完毕3XX Redirection(重定向状态 ...

  6. NOIP模拟80

    学考+OJ改名祭 T1 邻面合并 解题思路 状压 DP ...(于是贪心竟然有 60pts 的高分?? code) 状态设计的就非常妙了,如果状态是 1 就表示是一个分割点也就是一个矩形的右边界. 那 ...

  7. Python技法3:匿名函数、回调函数和高阶函数

    1.定义匿名或内联函数 如果我们想提供一个短小的回调函数供sort()这样的函数用,但不想用def这样的语句编写一个单行的函数,我们可以借助lambda表达式来编写"内联"式的函数 ...

  8. Hash窃取与传递

    Hash窃取与传递 NTHASH(NTLM) 在 Windows中, 存储的密码Hash就叫做 NTHash,也叫做 NTLM,其中NTLM 全称是 "NT LAN Manager" ...

  9. C++ 与 Visual Studio 2019 和 WSL(四)——库组件

    C++ 与 Visual Studio 2019 和 WSL (库组件) Reference 在 C++ 项目中使用库和组件 | Microsoft Docs 演练:创建和使用自己的动态链接库 (C+ ...

  10. leetcode779 第k个语法符号。

    直接找规律. 第一行 0 第二行 01 第三行 0110 第四行 01101001 可以发现,第n行的数量比第n-1行多了一倍,并且前半部分是和第n-1行一样的,后半部分是前半部分"按位取反 ...