Link:

BZOJ 2668 传送门

Solution:

重点在于对于每条转移路径:首尾算一次,中间节点算两次

可以一点拆三点,将原流量拆成入流量和出流量

但其实也可以就拆两点,分前后是否是一首尾点一普通点来确定是否有一条路径只占用1流量

Code:

#include <bits/stdc++.h>

using namespace std;
#define X first
#define Y second
typedef long long ll;
typedef pair<int,int> P;
const int MAXN=1e5+,INF=<<;
int n,m,cnt1,cnt2;char dat[][][],lmt[][]; namespace mcmf
{
struct edge
{int to,cap,cost,rev;};
vector<edge> a[MAXN];
int S,T,h[MAXN],dist[MAXN],preV[MAXN],preE[MAXN],maxf,minc; void add_edge(int from,int to,int cap,int cost)
{
a[from].push_back(edge{to,cap,cost,a[to].size()});
a[to].push_back(edge{from,,-cost,a[from].size()-});
}
void min_cost_flow(int f)
{
while(f>)
{
priority_queue<P,vector<P>,greater<P> > que;
fill(dist,dist+T+,INF);
dist[S]=;que.push(P(,S));
while(!que.empty())
{
P t=que.top();que.pop();
int v=t.Y;if(dist[v]<t.X) continue; for(int i=;i<a[v].size();i++)
{
edge &e=a[v][i];
if(e.cap>&&dist[e.to]>dist[v]+e.cost+h[v]-h[e.to])
dist[e.to]=dist[v]+e.cost+h[v]-h[e.to],
preV[e.to]=v,preE[e.to]=i,que.push(P(dist[e.to],e.to));
}
}
if(dist[T]==INF) break;
for(int i=;i<=T;i++) h[i]+=dist[i]; int d=f;
for(int i=T;i!=S;i=preV[i])
d=min(d,a[preV[i]][preE[i]].cap);
f-=d;minc+=d*h[T];maxf+=d;
for(int i=T;i!=S;i=preV[i])
{
edge &e=a[preV[i]][preE[i]];
e.cap-=d,a[i][e.rev].cap+=d;
}
}
}
}
using namespace mcmf;
int dx[]={,,,-,-,-,,};
int dy[]={,-,,,-,,,-};
int idx(int x,int y,int z){return (x-)*m+y+n*m*z;} int main()
{
scanf("%d%d",&n,&m);
S=;T=*n*m+;
for(int i=;i<=n;i++) scanf("%s",dat[][i]+);
for(int i=;i<=n;i++) scanf("%s",dat[][i]+);
for(int i=;i<=n;i++) scanf("%s",lmt[i]+);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
{
if(dat[][i][j]=='')
cnt1++,add_edge(S,idx(i,j,),,);
if(dat[][i][j]=='')
cnt2++,add_edge(idx(i,j,),T,,);
if(dat[][i][j]==dat[][i][j])
add_edge(idx(i,j,),idx(i,j,),(lmt[i][j]-'')/+dat[][i][j]-'',);
else add_edge(idx(i,j,),idx(i,j,),(lmt[i][j]-''+)/,); for(int k=;k<;k++)
{
int fx=i+dx[k],fy=j+dy[k];
if(fx<||fx>n||fy<||fy>m) continue;
add_edge(idx(i,j,),idx(fx,fy,),INF,);
}
} min_cost_flow(INF);
if(cnt1!=cnt2||maxf!=cnt1) puts("-1");
else printf("%d",minc);
return ;
}

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

  1. BZOJ 2668 交换棋子(费用流)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2668 题意:有一个n行m列的黑白棋盘,你每次可以交换两个相邻格子中的棋子,最终达到目标状 ...

  2. 【BZOJ】【2668】【CQOI2012】交换棋子

    网络流/费用流 跪跪跪,居然还可以这样建图…… 题解:http://www.cnblogs.com/zig-zag/archive/2013/04/21/3033485.html 考虑每个点的交换限制 ...

  3. BZOJ 2668 [cqoi2012]交换棋子 | 最小费用最大流

    传送门 BZOJ 2668 题解 同时分别限制流入和流出次数,所以把一个点拆成三个:入点in(x).中间点mi(x).出点ou(x). 如果一个格子x在初始状态是黑点,则连(S, mi(x), 1, ...

  4. BZOJ 2668: [cqoi2012]交换棋子

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

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

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

  6. BZOJ2668: [cqoi2012]交换棋子

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

  7. [cqoi2012]交换棋子

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

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

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

  9. [BZOJ 4563]放棋子

    [BZOJ 4563]放棋子 题目 给你一个N*N的矩阵,每行有一个障碍,数据保证任意两个障碍不在同一行,任意两个障碍不在同一列,要求你在这个矩阵上放N枚棋子(障碍的位置不能放棋子),要求你放N个棋子 ...

随机推荐

  1. 01-QQ 3-最终重构版 Demo示例程序源代码

      源代码下载链接:01-QQ 3.zip292.5 KB // QQAppDelegate.h Map // //  QQAppDelegate.h //  01-QQ // //  Created ...

  2. RabbitMq related

    # RabbitMq related Integration of message queuing tools with systems is the usual solution to handle ...

  3. 逃生(HDU4857 + 反向拓扑排序)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4857 题面是中文题面,就不解释题意了,自己点击链接去看下啦~这题排序有两个条件,一个是按给定的那个序列 ...

  4. bzoj 1202 并查集

    首先我们知道若干区间和信息,判断给出信息是否合法,可以用并查集维护,我们用dis[x]表示x到father[x]的距离为多少,即区间father[x]到x的长度,这样我们可以在路径压缩的时候维护dis ...

  5. supervisor 简单使用

    supervisor是一个c/s系统,被用来在类Unix系统中监控进程状态.supervisor使用python开发. 服务端进程为supervisord,主要负责启动自身及其监控的子进程,响应客户端 ...

  6. java===java基础学习(10)---对象构造

    重载 如果多个方法有相同的名字,不同的参数,便产生了重载.编译器必须挑选出具体执行哪个方法,他通过用各个方法给出的参数类I型那个与特定方法调用所使用的值类型进行匹配来挑选出相应的方法.如果编译器找不到 ...

  7. 【bzoj1798】【AHOI2009】维护序列

    练一下线段树模板,区间乘法. #include<bits/stdc++.h> #define lson (o<<1) #define rson (o<<1|1) ; ...

  8. MACBOOK 总是断网怎么办

    MACBOOK 连接 wifi 老是断网.焦躁不安 看图,二个方法,第一就搞定,

  9. linux命令(21):more命令

    实例1:显示文件中从第3行起的内容 [root@host-172-168-80-55 home]# cat test.log aaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb ...

  10. Dubbo 用户手册学习笔记 —— Dubbo架构

    Dubbo的架构 节点角色说明 节点 角色说明 Provider 服务提供方 Consumer 服务消费方 Registry 服务注册与发现的注册中心 Monitor 统计服务的调用次数和调用时间的监 ...