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费用流
期末结束,竞赛生活继续开始,先怒刷完寒假作业再说 至于期末考试,数学跪惨,各种哦智障错,还有我初中常用的建系大法居然被自己抛至脑后,看来学的还是不扎实,以后数学要老老实实学.物理被永哥黑了两分,然后很 ...
随机推荐
- 【总结】2017年当下最值得你关注的前端开发框架,不知道你就OUT了!
近几年随着 jQuery.Ext 以及 CSS3 的发展,以 Bootstrap 为代表的前端开发框架如雨后春笋般挤入视野,可谓应接不暇. 在这篇分享中,我将总结2017年当下最值得你关注的前端开发框 ...
- JavaScript事件冒泡与捕获
event.preventDefault(); 如果event.cancelable的值为true,可以取消默认事件 event.cancelable; 元素是否可以取消 ...
- 2017-2018-2 20179205《网络攻防技术与实践》Windows攻击实验
Windows攻击实验 实验描述: 使用Metaspoit攻击MS08-067,提交正确得到远程shell过程的截图(不少于五张). MS08-067漏洞介绍 MS08-067漏洞的全称为&quo ...
- linux nginx大量TIME_WAIT的解决办法--转
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' TIME_WAIT 8535 CLOSE_WAIT 5 FIN ...
- Linux SSH Backdoor分析排查
1.SSH后门分类 SSH后门方式有以下几种 软链接 SSH Server wrapper SSH Keylogger 2.软链接 利用方法 [root@helen]# ln -sf /usr/sbi ...
- Redis—数据结构之sds
Redis是一个Key Value数据库.Redis有5种数据类型:字符串.列表.哈希.集合.有序集合.而字符串的底层实现方法之一就是使用sds.以下描述中请读者注意区分sds是指简单动态字符串这一数 ...
- echarts 移动端地图数据可视化开发教程
如上效果图: 以下未代码: <!doctype html> <html lang="en"> <head> <meta charset ...
- GBDT+LR simple例子
卧槽,本来猜GBDT获取的组合特征,需要自己去解析GBDT的树,scikit learn里面竟然直接调用apply函数就可以了 # 弱分类器的数目 n_estimator = 10 # 随机生成分类数 ...
- Linux下配置Samba服务器全过程
Linux下配置Samba服务器全过程 user级别的samba的配置 http://www.linuxidc.com/Linux/2014-11/109234.htm http://www.linu ...
- 不同Linux机器之间拷贝文件
不同的Linux之间copy文件常用有3种方法: 第一种就是ftp,也就是其中一台Linux安装ftp Server,这样可以另外一台使用ftp的client程序来进行文件的copy. 第二种方法就是 ...