【BZOJ】【2668】【CQOI2012】交换棋子
网络流/费用流
跪跪跪,居然还可以这样建图……
题解: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】交换棋子的更多相关文章
- BZOJ 2668: [cqoi2012]交换棋子
2668: [cqoi2012]交换棋子 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 1112 Solved: 409[Submit][Status ...
- BZOJ 2668 [cqoi2012]交换棋子 | 最小费用最大流
传送门 BZOJ 2668 题解 同时分别限制流入和流出次数,所以把一个点拆成三个:入点in(x).中间点mi(x).出点ou(x). 如果一个格子x在初始状态是黑点,则连(S, mi(x), 1, ...
- BZOJ.2668.[CQOI2012]交换棋子(费用流zkw)
题目链接 首先黑白棋子的交换等价于黑棋子在白格子图上移动,都到达指定位置. 在这假设我们知道这题用网络流做. 那么黑棋到指定位置就是一条路径,考虑怎么用流模拟出这条路径. 我们发现除了路径的起点和终点 ...
- 2668: [cqoi2012]交换棋子
Description 有一个n行m列的黑白棋盘,你每次可以交换两个相邻格子(相邻是指有公共边或公共顶点)中的棋子,最终达到目标状态.要求第i行第j列的格子只能参与mi,j次交换. Input 第一行 ...
- BZOJ2668: [cqoi2012]交换棋子
题解: 可以戳这里:http://www.cnblogs.com/zig-zag/archive/2013/04/21/3033485.html 其实自己yy一下就知道这样建图的正确性了. 感觉太神奇 ...
- [cqoi2012]交换棋子
2668: [cqoi2012]交换棋子 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 1334 Solved: 518[Submit][Stat ...
- 【BZOJ2668】[cqoi2012]交换棋子 费用流
[BZOJ2668][cqoi2012]交换棋子 Description 有一个n行m列的黑白棋盘,你每次可以交换两个相邻格子(相邻是指有公共边或公共顶点)中的棋子,最终达到目标状态.要求第i行第j列 ...
- 洛谷 P3159(BZOJ 2668)[CQOI2012]交换棋子
有一个\(n\)行\(m\)列的黑白棋盘,你每次可以交换两个相邻格子(相邻是指有公共边或公共顶点)中的棋子,最终达到目标状态.要求第\(i\)行第\(j\)列的格子只能参与\(m[i][j]\)次交换 ...
- BZOJ2668:[CQOI2012]交换棋子——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=2668 https://www.luogu.org/problemnew/show/P3159#sub ...
- P3159 [CQOI2012]交换棋子
思路 相当神奇的费用流拆点模型 最开始我想到把交换黑色棋子看成一个流流动的过程,流从一个节点流向另一个节点就是交换两个节点,然后把一个位置拆成两个点限制流量,然后就有了这样的建图方法 S向所有初始是黑 ...
随机推荐
- jquery不熟悉的方法
1.jquery有一个筛选api find. 语法很简单,比如: HTML 代码: <p><span>Hello</span>, how are you?</ ...
- JavaScript相关知识
JavaScript的语法规则 l JavaScript区分大小写 比如变量a和变量A是不一样的变量,要严格区分大小写 l JavaScript脚本程序须嵌入在HTML文件中 因为javascript ...
- redis 配置文件解读
# Redis 配置文件 # 当配置中需要配置内存大小时,可以使用 1k, 5GB, 4M 等类似的格式,其转换方式如下(不区分大小写) # # 1k => 1000 bytes # 1kb = ...
- 小木棍 (codevs 3498)题解
[问题描述] 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过100. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长 ...
- SQL Server 基础:Cast和Convert的区别
CAST 和 CONVERT 都可以将某种数据类型的表达式显式转换为另一种数据类型. 语法: CAST ( expression AS data_type ) CONVERT (data_type[( ...
- WIN8+VS2013编写发布WCF之二(部署)
上文简介了如何建立WCF工程并且调试,下面说一下如何部署. 本文将陆陆续续讲述三种部署方式,随着项目的进展将不断补全. 声明: 用管理员身份打开VS2013,发布前请将程序的.net版本改成与服务器相 ...
- entityFramework使用 codefirst
新建项目 用nuget安装entityFramework,Install-Package Entityframework 建一个model和context //[Table("Custome ...
- 菜鸟学习Struts——国际化
一.概念 国际化:界面上的语言可以根据用户所在的地区改变显示语言. 如图: 二.实例 下面就一步一步的教大家利用Struts实现国际化. 1.编写资源文件 这个资源文件就是界面上显示的字符,资源文件里 ...
- .NET开源工作流RoadFlow-流程设计-流程属性设置
打开流程设计器点击新建流程后会弹出新流程属性设置框,属性设置包括基本信息,数据连接和标识字段三项设置. 1.基本信息 流程ID:系统自动给每个流程分配的一个唯一ID. 流程名称:给您的新流程取一个名称 ...
- javascript 关于Date 时间类型 处理方法
上一篇博客中和大家分享了关于 字符串转时间类型 这一篇顺便整理下 javascript 中 Date 类型的一些方法 var time = new Date(); var year=time.getY ...