网络流/费用流


  跪跪跪,居然还可以这样建图……

  题解:http://www.cnblogs.com/zig-zag/archive/2013/04/21/3033485.html

考虑每个点的交换限制的约束,一看就知道是点容量,但是这里不是一分为二,而是一分为三。

首先我们把问题化简,变成对于原图上所有黑点,找到一个新图中的黑点,进行多次交换后到达。我们看到多次交换实际上是走了一条路径(这里不是最短 路)。对于这条路径的起点和终点,仅进行了1次交换,而路径上的其他点都交换了2次。所以我们需要构造一种图来把这个交换次数的差异体现出来,于是:

对于每个点一分为三,分为p0,p1,p2,对于每个点,如果它是原图中得黑点,连 边<p1,p0,c/2,0>,<p0,p2,(c+1)/2>,<st,p0,1,0>;如果它是新图中得黑点, 连边<p1,p0,(c+1)/2>,<p0,p2,c/2,0>,<p0,ed,1,0>;如果它在两个图中都是 白点,那么连边<p1,p0,c/2,0>,<p0,p2,c/2,0>。这样就可以体现出点容量的差异了。

然后对于原图中可以交换的两个点(i,j)连接<pi2,pj1,inf,1>,那么这种边每流过1的流量就意味着(i,j)交换了一次,那么费用就是最终的答案了。

 /**************************************************************
Problem: 2668
User: Tunix
Language: C++
Result: Accepted
Time:24 ms
Memory:48464 kb
****************************************************************/ //BZOJ 2668
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
using namespace std;
inline int getint(){
int v=,sign=; char ch=getchar();
while(ch<''||ch>''){ if (ch=='-') sign=-; ch=getchar();}
while(ch>=''&&ch<=''){ v=v*+ch-''; ch=getchar();}
return v*sign;
}
const int N=,M=,INF=~0u>>;
typedef long long LL;
/******************tamplate*********************/
char s1[][],s2[][],s3[][];
int n,m,a[][],b[][],c[][],num[][],b1,b2,ans,flow,tot;
inline int gcd(int a,int b){return b ? gcd(b,a%b) : a;}
bool judge(int x,int y){
int q=x*x-y*y,s=sqrt(q);
if (s*s==q && gcd(y,s)==) return ;
return ;
}
struct edge{int from,to,v,c;};
struct Net{
edge E[M];
int head[N],next[M],cnt;
void ins(int x,int y,int z,int c){
E[++cnt]=(edge){x,y,z,c};
next[cnt]=head[x]; head[x]=cnt;
}
void add(int x,int y,int z,int c){
ins(x,y,z,c); ins(y,x,,-c);
}
int from[N],Q[M],d[N],S,T;
bool inq[N];
bool spfa(){
int l=,r=-;
F(i,,T) d[i]=INF;
d[S]=; Q[++r]=S; inq[S]=;
while(l<=r){
int x=Q[l++];
inq[x]=;
for(int i=head[x];i;i=next[i])
if(E[i].v> && d[x]+E[i].c<d[E[i].to]){
d[E[i].to]=d[x]+E[i].c;
from[E[i].to]=i;
if (!inq[E[i].to]){
Q[++r]=E[i].to;
inq[E[i].to]=;
}
}
}
return d[T]!=INF;
}
void mcf(){
int x=INF,y,z;
for(int i=from[T];i;i=from[E[i].from])
x=min(x,E[i].v);
for(int i=from[T];i;i=from[E[i].from]){
E[i].v-=x;
E[i^].v+=x;
}
flow+=x;
ans+=x*d[T];
}
void init(){
n=getint(); m=getint(); cnt=;
tot=n*m; S=; T=tot*+;
F(i,,n) scanf("%s",s1[i]+);
F(i,,n) scanf("%s",s2[i]+);
F(i,,n) scanf("%s",s3[i]+);
F(i,,n) F(j,,m){
a[i][j]=s1[i][j]-''; if(a[i][j]) b1++;
b[i][j]=s2[i][j]-''; if(b[i][j]) b2++;
c[i][j]=s3[i][j]-'';
if (a[i][j]&&b[i][j]) a[i][j]=b[i][j]=,b1--,b2--;
}
F(i,,n) F(j,,m){
int now=(i-)*m+j;
num[i][j]=now;
if (a[i][j]){
add(S,now,,);
add(tot+now,now,c[i][j]/,);
add(now,*tot+now,(c[i][j]+)/,);
}else if(b[i][j]){
add(now,T,,);
add(tot+now,now,(c[i][j]+)/,);
add(now,*tot+now,c[i][j]/,);
}else{
add(tot+now,now,c[i][j]/,);
add(now,*tot+now,c[i][j]/,);
}
}
F(i,,n) F(j,,m){
if (i>) add(*tot+num[i][j],tot+num[i-][j],INF,);
if (j>) add(*tot+num[i][j],tot+num[i][j-],INF,);
if (i<n) add(*tot+num[i][j],tot+num[i+][j],INF,);
if (j<m) add(*tot+num[i][j],tot+num[i][j+],INF,);
if (i> && j>) add(*tot+num[i][j],tot+num[i-][j-],INF,);
if (i<n && j<m) add(*tot+num[i][j],tot+num[i+][j+],INF,);
if (i> && j<m) add(*tot+num[i][j],tot+num[i-][j+],INF,);
if (i<n && j>) add(*tot+num[i][j],tot+num[i+][j-],INF,);
}
if (b1==b2){
while(spfa()) mcf();
if (flow!=b1) ans=-;
}else ans=-;
printf("%d\n",ans);
}
}G1; int main(){
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
// freopen("2668.out","w",stdout);
#endif
G1.init();
return ;
}

【BZOJ】【2668】【CQOI2012】交换棋子的更多相关文章

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

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

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

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

  3. BZOJ.2668.[CQOI2012]交换棋子(费用流zkw)

    题目链接 首先黑白棋子的交换等价于黑棋子在白格子图上移动,都到达指定位置. 在这假设我们知道这题用网络流做. 那么黑棋到指定位置就是一条路径,考虑怎么用流模拟出这条路径. 我们发现除了路径的起点和终点 ...

  4. 2668: [cqoi2012]交换棋子

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

  5. BZOJ2668: [cqoi2012]交换棋子

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

  6. [cqoi2012]交换棋子

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

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

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

  8. 洛谷 P3159(BZOJ 2668)[CQOI2012]交换棋子

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

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

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

  10. P3159 [CQOI2012]交换棋子

    思路 相当神奇的费用流拆点模型 最开始我想到把交换黑色棋子看成一个流流动的过程,流从一个节点流向另一个节点就是交换两个节点,然后把一个位置拆成两个点限制流量,然后就有了这样的建图方法 S向所有初始是黑 ...

随机推荐

  1. spark性能调优:资源优化

    在开发完Spark作业之后,就该为作业配置合适的资源了.Spark的资源参数,基本都可以在spark-submit命令中作为参数设置.很多Spark初学者,通常不知道该设置哪些必要的参数,以及如何设置 ...

  2. postgresql 分区表

    1.普通方式建立主表 create table tbl_partition( id integer, name ), gender boolean, join_date date, dept ) ) ...

  3. Windows7不能打开telnet功能

    在dos窗口中输入telnet命令提示如下: 解决方法是打开控制面板中的程序和功能,选择打开或关闭Window是功能,如下: 勾选上面的Telnet客户端,然后确定,出现下图.稍等片刻重新打开命令行, ...

  4. 第三章 设计程序架构 之 设计实现Windows Azure 角色生命周期

    1. 概述 Windows Azure 是微软的云计算平台.用于 在微软数据中心 通过全局网络 生成.发布和管理应用程序. 本章内容包括 startup tasks 以及  实现 Start, Run ...

  5. python匿名函数(lambda)

    简单来说,编程中提到的 lambda 表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数 当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方 ...

  6. 007-python基础-pyc是什么

    3.1 解释型语言和编译型语言 计算机是不能够识别高级语言的,所以当我们运行一个高级语言程序的时候,就需要一个"翻译机"来从事把高级语言转变成计算机能读懂的机器语言的过程.这个过程 ...

  7. eclipse新建android项目,编译出错解决方法

    1.新建android项目 2.在libs中,将android-support-v4.jar添加到生成目录 3.如果项目引用了ActionBar等,需要引用V7的话,添加外部Jar包,路径为eclip ...

  8. Unity Scripting Tutorials 要点记录

    (搬运自我在SegmentFault的博客) 这几天通过Unity官网的Unity Scripting Tutorials的视频学习Unity脚本,观看的过程中做了记录.现在,整理了一下笔记,供自己以 ...

  9. 如何在Eclipse中配置Tomcat

    1.Eclipse EE 配置Tomcat Eclipse EE 主要用于Java Web开发和J2EE项目开发.Eclipse EE中配置Tomcat比较简单,新建一个Tomcat Server即可 ...

  10. ES6 入门系列 - 函数的扩展

    1函数参数的默认值 基本用法 在ES6之前,不能直接为函数的参数指定默认值,只能采用变通的方法. function log(x, y) { y = y || 'World'; console.log( ...