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. POJ 2431 Expedition (优先队列+贪心)

    题目链接 Description A group of cows grabbed a truck and ventured on an expedition deep into the jungle. ...

  2. hdu 1003 Max Sum (DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1003 Max Sum Time Limit: 2000/1000 MS (Java/Others)   ...

  3. 自定义ToolBar

    一.Toolbar的简介 Toolbar 是 android 5.0 引入的一个新控件,Toolbar出现之前,我们很多时候都是使用ActionBar以及ActionActivity实现顶部导航栏的, ...

  4. Android控件——ToggleButton多状态按钮(实现灯泡的开关)

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAxoAAAFxCAIAAAB7jkm1AAAgAElEQVR4nOy9eXgUVb7/Dy7j3BnH8T

  5. perl发送post数据

    把post数据写进一个匿名数组里就行 #!/usr/bin/env perl -w use strict; use LWP::UserAgent; my $ua = LWP::UserAgent-&g ...

  6. linux编程之信号

    信号(signal)机制是UNIX系统中最为古老的进程之间的通信机制,它用在一个或多个进程之间传递异步信号,信号可以由各种异步事件产生,如: 键盘中断等等,在Linux 的shell 中,也可以使用信 ...

  7. 限制printk打印频率函数printk_ratelimit【转】

    转自:http://blog.csdn.net/lkkey80/article/details/45190095 版权声明:博文地址 http://blog.csdn.net/lkkey80?view ...

  8. sicily 1172. Queens, Knights and Pawns

    Description You all are familiar with the famous 8-queens problem which asks you to place 8 queens o ...

  9. 【HDU5306】Gorgeous Sequence

    这个题目是Segment-Tree-beats的论文的第一题. 首先我们考虑下这个问题的不同之处在于,有一个区间对x取max的操作. 那么如何维护这个操作呢? 就是对于线段树的区间,维护一个最大值标记 ...

  10. LVS负载均衡DR模式

    什么是集群? 一组相互独立的计算机,利用高速通信网络组成的一个计算机系统,对于客户机来说像是一个单一服务器,实际上是一组服务器.简而言之,一堆机器协同工作就是集群.集群的基本特点:高性能.高并发.高吞 ...