[Wf2011]Chips Challenge

  • problem
  • solution
  • code

problem

BZOJ2673

solution

.

首先得知道这是网络流,但真的看不出来啊!!我真的郁闷啊( ̄﹏ ̄;)

在知道做法是网络流后,初读题,肯定会想到将行列分左右点,[1,n][1,n][1,n]表示行,[n+1,2n][n+1,2n][n+1,2n]表示列。

然后就发现举步维艰,因为题目要维护的两个条件都不是很好操作。

iii 行 iii 列零件数一样,且每行零件数不能超过总数的 AB\frac{A}{B}BA​。

这两个限制条件都没有明确具体零件个数要求,是随着全局动态变化的。

所以无法变成网络流上的容量限制。

唯一知道的限制就是每行每列可放芯片的最大数量。

【可放指的是 . /C 的点】

注意到 nnn 的限制很小,不妨考虑枚举每行可放零件的最大值个数 MaxMaxMax。

如果能通过网络流求出总零件数量 tottottot,就可以逆向判断 Max≤ABtot⇒Max∗B≤A∗totMax\le \frac{A}{B}tot\Rightarrow Max*B\le A*totMax≤BA​tot⇒Max∗B≤A∗tot。

而网络流是最大流,是尽量做到流满的,所以 tottottot 一定会尽可能的大。

增长同向平行,最大流就是在做尽量满足判断式子的过程。

所以如果最大流的结果还是不满足上面的不等式,只能说明 MaxMaxMax 不是合法的。

自然地想到,对于可放芯片的位置 (i,j)(i,j)(i,j) 进行 iii 行向 jjj 列连边,容量为 111 。

这样去跑网络流,跑出的最大流确实是最多能放的芯片数量,但是这样并没有考虑到 iii 行 iii 列相等的限制。

因为不能知道第 iii 行和第 iii 列具体放了多少个芯片,没有明确的容量限制。

但是转化一下,第 iii 行放了芯片的位置和第 iii 列没放芯片的位置加起来一共是等于 nnn 的。

所以想到新建一个连接点 kkk,分别让行列点向 kkk 连边。

行连接的边流过的流量来表示行放芯片的个数,列连接的边流过的流量来表示列不放芯片的个数。

行列与 kkk 之间的边容量设为 ∞∞∞。

然后连接点向 ttt 连边,容量为 nnn,保证 k→tk\rightarrow tk→t 的边满流即可。

因为这样代表着第 iii 行放的个数和第 iii 列不放的个数加在一起是等于 nnn 的,变相地满足第 iii 行和第 iii 列个数相同的限制。

但是怎么能一些边流了表示不选,一些边流了表示要选。最大流上面看到了是不能做到的,那就只能考虑最小费用了。

行 iii 流给连接点 kkk 的表示要放的芯片,列 iii 流给 kkk 的表示不放的芯片,所以 i→ji\rightarrow ji→j 这种流给其它列点就应当表示 (i,j)(i,j)(i,j) 不放芯片,所以只有 iii 行 jjj 列是 . 才有选择不放的可能。

为了记录这样的边流了多少,就把这种边带上费用 111,跑最小费用就是尽可能减少不放的,即最大化放的芯片。

除了这样的边,其余边费用就为 000,属于要跑最大流。

别忘了,一开始枚举的每行放芯片个数的限制,所以行与连接点之间的容量应该修改为 MaxMaxMax。

注意到,现在的网络还有一个冗余的地方,列 iii 的出边只有连接点 kkk,且容量为 ∞∞∞,所以可以将列 iii 与连接点进行合并。

那么现在的网络,行 iii 的流量只有两种去向:经过列 iii 最多流 MaxMaxMax 个,剩下的都是流到其他列 jjj 地方,表示不放芯片,且带有费用 111。

最后最大流减去最小费用就是真正放的芯片个数,再减去一定放的 C 个数就是新放的芯片个数。

最后记得还有行列分别与源汇的连边。

通过 s→is\rightarrow is→i 容量为第 iii 行可放的芯片数量来限制第 iii 行放置的个数。

通过 j→tj\rightarrow tj→t 容量为第 jjj 列可放的芯片数量来限制第 jjj 列放置的个数。【准确来说是 j+n→tj+n\rightarrow tj+n→t,大家意会就行】

最后让这个网络满流即可。

总结一下建图过程:
{s→irowi,0i+n→ncoli,0i→j+n1,1(ch[i][j]=′.′)i→i+nMax,0\begin{cases}s\rightarrow i\quad \quad \quad row_i,0\\i+n\rightarrow n\quad col_i,0\\i\rightarrow j+n\quad 1,1\ (ch[i][j]='.')\\i\rightarrow i+n\quad Max,0\end{cases} ⎩⎪⎪⎪⎨⎪⎪⎪⎧​s→irowi​,0i+n→ncoli​,0i→j+n1,1 (ch[i][j]=′.′)i→i+nMax,0​

code

#include <bits/stdc++.h>
using namespace std;
#define maxn 105
#define maxm 5005
int n, a, b, s, t, cnt;
bool vis[maxn];
char ch[maxn][maxn];
int dis[maxn], head[maxn], lst[maxn], row[maxn], col[maxn];
struct node { int to, nxt, flow, w; }E[maxm];
queue < int > q;void addedge( int u, int v, int flow, int w ) {E[cnt] = { v, head[u], flow, w };head[u] = cnt ++;E[cnt] = { u, head[v], 0, -w };head[v] = cnt ++;
}bool spfa() {memset( dis, 0x7f, sizeof( dis ) );memset( lst, -1, sizeof( lst ) );dis[s] = 0; q.push( s );while( ! q.empty() ) {int u = q.front(); q.pop(); vis[u] = 0;for( int i = head[u];~ i;i = E[i].nxt ) {int v = E[i].to;if( dis[v] > dis[u] + E[i].w and E[i].flow ) {dis[v] = dis[u] + E[i].w;lst[v] = i;if( ! vis[v] ) vis[v] = 1, q.push( v );}}}return ~ lst[t];
}void MCMF( int &flow, int &cost ) {flow = cost = 0;while( spfa() ) {int Min = 1e9;for( int i = lst[t];~ i;i = lst[E[i ^ 1].to] )Min = min( Min, E[i].flow );for( int i = lst[t];~ i;i = lst[E[i ^ 1].to] )cost += E[i].w * Min, E[i].flow -= Min, E[i ^ 1].flow += Min;flow += Min;}
}int main() {int Case = 0;while( ~ scanf( "%d %d %d", &n, &a, &b ) ) {if( ! n and ! a and ! b ) break;memset( row, 0, sizeof( row ) );memset( col, 0, sizeof( col ) );s = 0, t = n << 1 | 1;int sum = 0, used = 0;for( int i = 1;i <= n;i ++ ) {scanf( "%s", ch[i] + 1 );for( int j = 1;j <= n;j ++ )if( ch[i][j] != '/' ) {sum ++, row[i] ++, col[j] ++;used += ch[i][j] == 'C';}}int ans = -1;for( int Max = 0, flow, cost;Max <= n;Max ++ ) {memset( head, -1, sizeof( head ) ); cnt = 0;for( int i = 1;i <= n;i ++ ) {addedge( s, i, row[i], 0 );addedge( i + n, t, col[i], 0 );addedge( i, i + n, Max, 0 );for( int j = 1;j <= n;j ++ )if( ch[i][j] == '.' ) addedge( i, j + n, 1, 1 );}MCMF( flow, cost );if( flow == sum and Max * b <= ( sum - cost ) * a )ans = max( ans, sum - cost );}printf( "Case %d: ", ++ Case );if( ~ ans ) printf( "%d\n", ans - used );else printf( "impossible\n" );}return 0;
}

[Wf2011]Chips Challenge(最小费用最大流)相关推荐

  1. WF2011 Chips Challenge

    题目链接:WF2011 Chips Challenge 这道题有几个难点,但是用网络流的思想去做是很明显的. 我们枚举当前可以放多少个,然后check. 怎么解决第i行,第i列个数相等. 怎么解决最多 ...

  2. 乌鲁木齐网络赛J题(最小费用最大流模板)

    ACM ICPC 乌鲁木齐网络赛 J. Our Journey of Dalian Ends 2017-09-09 17:24 243人阅读 评论(0) 收藏 举报  分类: 网络流(33)  版权声 ...

  3. POJ - 2516 Minimum Cost 最小费用最大流

    题目链接 题意:给n,m,k表示商店数,储存店数,种类数 然后给n*k表示每个水果店需求每种种类的数量: 表示成 need[i][j] 再给m*k表示每个储存店每种种类数量: 表示成store[i][ ...

  4. pku The Windy's KM最小权匹配 or 最小费用最大流

    http://poj.org/problem?id=3686 题意: 给定n个玩具,有m个车间,给出每个玩具在每个车间的加工所需的时间mat[i][j]表示第i个玩具在第j个车间加工所需的时间,规顶只 ...

  5. c语言最小费用流_策略算法工程师之路-图优化算法(一)(二分图amp;最小费用最大流)...

    目录 1.图的基本定义 2.双边匹配问题 2.1 二分图基本概念 2.2 二分图最大匹配求解 2.3 二分图最优匹配求解 2.4 二分图最优匹配建模实例 2.4.1 二分图最优匹配在师生匹配中的应用 ...

  6. 有源汇上下界最小费用可行流 ---- P4553 80人环游世界(拆点 + 有源汇上下界最小费用可行流)

    题目链接 题目大意: 解题思路: 又是一道裸题 . 首先它要求第iii个点只经过ViViVi那么我们就拆点ai,ai+na_i,a_{i+n}ai​,ai+n​一个点为入点,一个为出点这条边的流量范围 ...

  7. 有源汇上下界最小费用可行流 ---- P4043 [AHOI2014/JSOI2014]支线剧情(模板)

    题目链接 题目大意: 解题思路: 有源汇上下界最小费用可行流模板题目来着 先建出一个有源汇上下界可行流的图,然后注意建图的时候要把每条边的下界的费用提前加到ans里面 然后再对图跑费用流,就是补齐费用 ...

  8. Doctor NiGONiGO’s multi-core CPU(最小费用最大流模板)

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=693 题意:有一个 k 核的处理器和 n 个工作,全部的工作都须要在一个核上处理一个单位的 ...

  9. 【最小费用最大流】Going Home

    概念: 在同一个网络中,可能存在多个总流量相同的最大流,我们可以在计算流量的基础之上,给网络中的弧增加一个单位流量的费用(简称费用),在确保流量最大的前提下总费用最小--最小费用最大流. C - Go ...

最新文章

  1. 机器学习算法面试—口述(4):决策树
  2. 黑马程序员--java基础--其他对象
  3. Git之常见的分支操作
  4. JSTL的错误“attribute test does not accept any expressions”解决方法
  5. fluke196c系统语言,原装二手福禄克Fluke196C 电工仪表
  6. iPhone 13 Pro苍岭绿真机首曝!网友:这次iPhone被渲染图坑惨了
  7. 什么舱位_把“订舱位”说成book warehouse position,外企不会要你
  8. 活动目录集成区域DNS服务
  9. Python爬虫之(八)数据提取-Beautiful Soup
  10. Spark深入浅出企业级最佳实践
  11. 联想服务器风扇智能调节,联想怎么调风扇转速
  12. echarts制作3D锥形金字塔
  13. bootmgr快速修复win7_【win7共享软件下载】win7共享软件(局域网共享)下载 v7.2.8 免费版...
  14. 给新建属性设置自己需要的快捷键
  15. ios客户端发现_华为爱奇艺手机活动开发总结
  16. MIB 浏览器的使用指导
  17. 计算机网络 王道考研2021 第六章:应用层 -- 域名系统 DNS、域名解析
  18. 华为服务器插键盘的位置,服务器如何调出软键盘
  19. 不同域名间的session共享
  20. 初三毕业班主任压力过大割喉自尽

热门文章

  1. 量子计算机是程序员的未来,研究者:量子计算机一旦成功问世,时间也许会失去存在的意义...
  2. qt绘制一圈圆_Qt绘制圆形,矩形等图形   绘制同心圆
  3. jquery 样式获取设置值_[JQuery] jQuery选择器ID、CLASS、标签获取对象值、属性、设置css样式...
  4. mysql connector c编程_MySQL数据库之MySQL Connector 编程
  5. 加个ing是什么意思_take的意思竟然是“要求”?奇奇怪怪的熟词僻义打卡终于来了!...
  6. java高并发类_Java 高并发之魂
  7. linux path减少,Linux的环境变量PATH中所带来的问题及解决方法
  8. android studio初始化设置,Android studio 初始设置
  9. 数据结构——二叉树的层次遍历
  10. leetcode209. 长度最小的子数组(滑动窗口)