BZOJ2673 [Wf2011]Chips Challenge 费用流 zkw费用流 网络流
https://darkbzoj.cf/problem/2673
有一个芯片,芯片上有N*N(1≤N≤40)个插槽,可以在里面装零件。
有些插槽不能装零件,有些插槽必须装零件,剩下的插槽随意。
要求装好之后满足如下两条要求:
1、第 i 行和第 i 列的零件数目必须一样多(1≤i≤N)。
2、第 i 行的零件数目不能超过总的零件数目的 A/B(1≤i≤N,0≤A≤B≤1000,B≠0)。
求最多可以另外放多少个零件(就是除掉必须放的)。如果无解输出impossible。
zkw费用流就是像跑最大流一样跑费用流,可以并行处理使得稠密图和二分图速度变快(据说)。
棋盘图依然是把横纵坐标拆成2n个点,每一个棋子可以用其横坐标到纵坐标的一条路表示。
棋盘上放最多的棋子相当于所有位置放上棋子后去掉最少的棋子,最小费用流处理就是给每一个可以去掉的棋子一个固定费用(1)。
i行和i列保留零件数目一样多就是从横坐标的i点到纵坐标的i点连一条费用为0流量固定为w的路。 w一定时,每一行每一列保留棋子的数量一定<=w。w上限是n所以我们可以枚举w建n次图跑网络流。
此时的最大流最小费用就是条件w下可以去掉的棋子数量的最小值(不仅要验证满足题目中的要求2,还要验证最大流=所有可以放棋子的位置的数量,因为保留棋子数量有时候可能小于某行列C的数量)(如果这个w跑最大流最小费用的方案不合法,那么就不存在w的合法条件)。
这个建n次图的方法有点像noip2017的那道搜索题目 NOIP2017 D2T2宝藏 都是按层次找的想法。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
#define LL long long
const int maxn=;
int n,A,B;
char ch[][];
int han[]={},shu[]={},sum,num,S,T,mx,cnt;
struct nod{
int x,y,next,v,co,rev;
}e[maxn];
int head[]={},tot=;
void init(int x,int y,int v,int co){
e[++tot].y=y;e[tot].x=x;e[tot].v=v;e[tot].co=co;e[tot].next=head[x];e[tot].rev=tot+;head[x]=tot;
e[++tot].y=x;e[tot].x=y;e[tot].v=;e[tot].co=-co;e[tot].next=head[y];e[tot].rev=tot-;head[y]=tot;
}
queue<int>q;
int dis[]={};bool vis[]={};
bool SPFA(){
memset(dis,,sizeof(dis));
memset(vis,,sizeof(vis));
mx=dis[];
q.push(S);vis[S]=;dis[S]=;
while(!q.empty()){
int x=q.front(),y;q.pop();vis[x]=;
for(int i=head[x];i;i=e[i].next){
y=e[i].y;
if(e[i].v>&&dis[y]>dis[x]+e[i].co){
dis[y]=dis[x]+e[i].co;
if(!vis[y]){
q.push(y);vis[y]=;
}
}
}
}
return dis[T]!=mx;
}
int dfs(int x,int val){
if(x==T){
cnt+=dis[T]*val;
return val;
}
int liu=,tv,y;vis[x]=;
for(int i=head[x];i;i=e[i].next){
y=e[i].y;
if(vis[y])continue;
if(e[i].v>&&dis[y]==dis[x]+e[i].co){
vis[y]=;
tv=dfs(y,min(val-liu,e[i].v));
liu+=tv;e[i].v-=tv;e[e[i].rev].v+=tv;
if(liu==val)break;
}
}
return liu;
}
int main(){
int C=;
while(~scanf("%d%d%d",&n,&A,&B)){
if(n==&&A==&&B==)break;
++C;
memset(han,,sizeof(han));memset(shu,,sizeof(shu));
sum=;cnt=;S=n*+;T=S+;
int zz=,ans=-;
for(int i=;i<n;i++){
scanf("%s",ch[i]);
for(int j=;j<n;j++){
if(ch[i][j]!='/'){
++han[i+];++shu[j+];++sum;
if(ch[i][j]=='C')++zz;
}
}
}
for(int w=;w<=n;w++){
tot=;memset(head,,sizeof(head));
for(int i=;i<=n;i++){
init(S,i,han[i],);
init(i+n,T,shu[i],);
init(i,i+n,w,);
for(int j=;j<=n;j++){
if(ch[i-][j-]=='.')init(i,j+n,,);
}
}int num=;cnt=;
while(SPFA()){memset(vis,,sizeof(vis));num+=dfs(S,sum);}
if(num==sum&&w*B<=(sum-cnt)*A)ans=max(ans,sum-cnt);
}cout<<endl;
if(ans==-)printf("Case %d: impossible\n",C);
else printf("Case %d: %d\n",C,ans-zz);
}
return ;
}
BZOJ2673 [Wf2011]Chips Challenge 费用流 zkw费用流 网络流的更多相关文章
- CSU 1948: 超级管理员(普通费用流&&zkw费用流)
Description 长者对小明施加了膜法,使得小明每天起床就像马丁的早晨一样. 今天小明早上醒来发现自己成了一位仓管员.仓库可以被描述为一个n × m的网格,在每个网格上有几个箱子(可能没有).为 ...
- Bzoj2673 3961: [WF2011]Chips Challenge 费用流
国际惯例题面:如果我们枚举放几个零件的话,第二个限制很容易解决,但是第一个怎么办?(好的,这么建图不可做)考虑我们枚举每行每列最多放几个零件t,然后计算零件总数sum.这样如果可行的话,则有t*B&l ...
- bzoj 3961: [WF2011]Chips Challenge【最小费用最大流】
参考:https://blog.csdn.net/Quack_quack/article/details/50554032 神建图系列 首先把问题转为全填上,最少扣下来几个能符合条件 先考虑第2个条件 ...
- 【BZOJ 2673】[Wf2011]Chips Challenge
题目大意: 传送门 $n*n$的棋盘,有一些位置可以放棋子,有一些已经放了棋子,有一些什么都没有,也不能放,要求放置以后满足:第i行和第i列的棋子数相同,同时每行的棋子数占总数比例小于$\frac{A ...
- bzoj3961[WF2011]Chips Challenge
题意 给出一个n*n的网格,有些格子必须染成黑色,有些格子必须染成白色,其他格子可以染成黑色或者白色.要求最后第i行的黑格子数目等于第i列的黑格子数目,且某一行/列的格子数目不能超过格子总数的A/B. ...
- [Wf2011]Chips Challenge
两个条件都不太好处理 每行放置的个数实际很小,枚举最多放x 但还是不好放 考虑所有位置先都放上,然后删除最少使得合法 为了凑所有的位置都考虑到,把它当最大流 但是删除最少,所以最小费用 行列相关,左行 ...
- zkw费用流+当前弧优化
zkw费用流+当前弧优化 var o,v:..] of boolean; f,s,d,dis:..] of longint; next,p,c,w:..] of longint; i,j,k,l,y, ...
- 学习了ZKW费用流
所谓ZKW费用流,其实就是Dinic. 若干年前有一个人发明了最小增广路算法,每次用BFS找一条增广路,时间O(nm^2) 然后被DinicD飞了:我们为什么不可以在长度不变时多路增广呢?时间O(n^ ...
- zkw费用流
期末结束,竞赛生活继续开始,先怒刷完寒假作业再说 至于期末考试,数学跪惨,各种哦智障错,还有我初中常用的建系大法居然被自己抛至脑后,看来学的还是不扎实,以后数学要老老实实学.物理被永哥黑了两分,然后很 ...
随机推荐
- 《区块链100问》第75集:大零币Zcash是什么?
Zcash,全称Zero Cash,简称ZEC,中文叫大零币,研发者为Zooko Wilcox,诞生于2011年11月9日. 采用零知识证明机制提供完全的支付保密性,是目前匿名性最强的数字资产.零知识 ...
- CSS 特殊性、继承与层叠
一.特殊性规则 选择器的特殊性由选择器本身的组件确定:特殊性由四个部分组成,其初始值为0,0,0,0. 1. 对于选择器中的每一个id,记0,1,0,0: 2. 对于选择器中的每一个类.伪 ...
- SqlServer存储过程(增删改查)
* IDENT_CURRENT 返回为任何会话和任何作用域中的特定表最后生成的标识值. CREATE PROCEDURE [dbo].[PR_NewsAffiche_AddNewsEntity] ( ...
- 与JavaWeb有关的故事(Web请求与Java IO)
作为一名后端屌丝程序员,对算法.并发.性能乐此不疲.但是,随着年龄和阅历的增加,显然叶落而不知秋的心态是不太能混了.尤其是,某T面试官在明知我是后端,且明确表示对HTTP协议不太熟的情况下,强行让我解 ...
- 一个不错的linux学习资料下载的网址
本文比较完整的讲述GNU make工具,涵盖GNU make的用法.语法.同时重点讨论如何为一个工程编写Makefile.作为一个Linux程序员,make工具的使用以及编写Makefile是必需的. ...
- checkbox 全选和取消
//全选 $("#checkall").click(function () { if (this.checked) { //如果当前点击的多选框被选中 $('input[type= ...
- HDU 6212 Zuma 2017青岛网络赛 区间DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6212 解法:看了眼题就发现这个BZOJ 1032不是一毛一样?但是BZOJ上那是个巨坑,数据有错,原来 ...
- 牛x的JavaScript编辑器你知道几个
英文:Martin Heller 译文:葡萄城控件 学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入学习交流群343599877,我们一起学前端! 对于JavaScript程序员来说,目前有很 ...
- 数据科学实战手册(R+Python)书中引用资料网址
本文会持续将<数据科学实战手册(R+Python)>一书中的附带参考资料网址手打出来, 方便访问. 由于书中的参考资料网址太多, 这个文档将可能花费一段时间才能完成. 第一章 P7 Rs ...
- UVA 10559 Blocks(区间DP&&递推)
题目大意:给你玩一个一维版的消灭星星,得分是当前消去的区间的长度的平方,求最大得分. 现在分析一下题目 因为得分是长度的平方,不能直接累加,所以在计算得分时需要考虑前一个状态所消去的长度,仅用dp[l ...