一、题目

有一个 \(n\times n\) 的矩阵,每个元素可能是 .C/ 的其中一种,分别表示可以放置芯片、已经放置了芯片、不能放置芯片,你可以分别决定是否可以放置芯片的位置放置芯片。

最后需要满足 \(\forall i\),第 \(i\) 行的芯片个数等于第 \(i\) 列的芯片个数,每一行的芯片个数都不超过总芯片个数的 \(\frac{A}{B}\),问在此情况下能额为放置的芯片个数最大值,如果怎么样都不合法输出 impossible

\(n\leq 40\)

二、解法

如果直接做的话并不好入手,我们考虑调整法,也就是让所有 . 的位置都放芯片再调整。

可以把芯片看成流量,我们可以套路地建出一个二分图。想象第 \(i\) 行的点上具有 \(a_i\) 点流量,第 \(i\) 列的点上具有 \(b_i\) 点流量(分别表示初始状态下它们的芯片个数),那么个数相等的条件可以转化成第 \(i\) 行和第 \(i\) 列同时减少 \(1\) 的流量。

但是最后点上就不能有残余流量,对于 . 的位置我们可以选择不放,设它的位置是 \((i,j)\) 那么它可以让 \(i\) 行 \(j\) 列同时减少 \(1\) 的流量。在此基础上我们还要最大化总芯片数,所以可以考虑增加费用这个意义,我们把同行同列的边费用设置为 \(0\),减少芯片的边费用设置为 \(1\),跑最小费用最大流即可。

还剩下最后一个限制:每一行的芯片个数都不超过总芯片个数A/B,我们可以枚举每一行的芯片个数 \(k\),把同行同列的流量设置为 \(k\),最后可以得到总芯片数 \(sum\),所以我们只需要判断下面两点:满流;\(sum\cdot A\geq k\cdot B\)

三、总结

调整法考虑寻找一个特殊的初始状态,再考虑如何描述增加\(/\)减少的过程。网络流加调整法的应用是常见的,类似的模型还有最小链覆盖,它就是把初始设置有 \(n\) 个链来调整。

网络流是属于图论的,所以它的思维方法中也涉及到思考原问题中的元素怎么对应到图上的每个量上去,比如本题因为要最大化总芯片数我们才考虑增加费用这一维。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <queue>
  5. using namespace std;
  6. const int M = 105;
  7. const int inf = 0x3f3f3f3f;
  8. int read()
  9. {
  10. int x=0,f=1;char c;
  11. while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
  12. while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
  13. return x*f;
  14. }
  15. int n,A,B,S,T,ans,tot,f[M],a[M],b[M];
  16. int m,dis[M],pre[M],flow[M],lst[M];
  17. struct edge{int v,f,c,next;}e[M*M];char s[M][M];
  18. void add(int u,int v,int F,int c)
  19. {
  20. e[++tot]=edge{v,F,c,f[u]},f[u]=tot;
  21. e[++tot]=edge{u,0,-c,f[v]},f[v]=tot;
  22. }
  23. int bfs()
  24. {
  25. queue<int> q;
  26. for(int i=0;i<=T;i++)
  27. dis[i]=inf,flow[i]=pre[i]=lst[i]=0;
  28. dis[S]=0;flow[S]=inf;q.push(S);
  29. while(!q.empty())
  30. {
  31. int u=q.front();q.pop();
  32. for(int i=f[u];i;i=e[i].next)
  33. {
  34. int v=e[i].v,c=e[i].c;
  35. if(dis[v]>dis[u]+c && e[i].f>0)
  36. {
  37. dis[v]=dis[u]+c;
  38. flow[v]=min(flow[u],e[i].f);
  39. pre[v]=u;lst[v]=i;
  40. q.push(v);
  41. }
  42. }
  43. }
  44. return flow[T]>0;
  45. }
  46. void zxy(int k)
  47. {
  48. int res=0,sum=0,all=0;
  49. S=0;T=2*n+1;tot=1;
  50. for(int i=0;i<=T;i++) f[i]=0;
  51. for(int i=1;i<=n;i++)
  52. {
  53. all+=a[i];
  54. add(S,i,a[i],0);
  55. add(i+n,T,b[i],0);
  56. add(i,i+n,k,0);
  57. }
  58. for(int i=1;i<=n;i++)
  59. for(int j=1;j<=n;j++) if(s[i][j]=='.')
  60. add(i,j+n,1,1);
  61. while(bfs())
  62. {
  63. int t=T;
  64. sum+=flow[t];
  65. res+=flow[t]*dis[t];
  66. while(t)
  67. {
  68. e[lst[t]].f-=flow[T];
  69. e[lst[t]^1].f+=flow[T];
  70. t=pre[t];
  71. }
  72. }
  73. if(sum==all && k*B<=(sum-res)*A)
  74. ans=max(ans,sum-res);
  75. }
  76. void work()
  77. {
  78. m=0;ans=-1;
  79. for(int i=1;i<=n;i++) a[i]=b[i]=0;
  80. for(int i=1;i<=n;i++)
  81. {
  82. scanf("%s",s[i]+1);
  83. for(int j=1;j<=n;j++)
  84. {
  85. m+=(s[i][j]=='C');
  86. a[i]+=(s[i][j]=='C' || s[i][j]=='.');
  87. b[j]+=(s[i][j]=='C' || s[i][j]=='.');
  88. }
  89. }
  90. for(int i=0;i<=n;i++) zxy(i);
  91. if(ans==-1) puts("impossible");
  92. else printf("%d\n",ans-m);
  93. }
  94. signed main()
  95. {
  96. int Case=0;
  97. while(~scanf("%d %d %d",&n,&A,&B) && n+A+B)
  98. {
  99. printf("Case %d: ",++Case);
  100. work();
  101. }
  102. }

UVA1104 Chips Challenge的更多相关文章

  1. 【题解】uva1104 chips challenge

    原题传送门 题目分析 给定一张n*n的芯片. '.'表示该格子可以放一个零件. 'C'表示该格子已经放了一个零件(不能拆下). '/'表示该格子不能放零件. 要求在芯片的现有基础上,放置尽可能多的零件 ...

  2. [2011WorldFinal]Chips Challenge[流量平衡]

    Chips Challenge Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  3. UVA1104 芯片难题 Chips Challenge

    题目链接 题意 网格上放点,有些强制放,有些不能放,有些可以放可以不放.要求: 第 \(i\) 行的点数 = 第 \(i\) 列的点数 每一行每一列的点数不超过总点数的 \(k\) 倍(\(k\) 已 ...

  4. 【UVALive - 5131】Chips Challenge(上下界循环费用流)

    Description A prominent microprocessor company has enlisted your help to lay out some interchangeabl ...

  5. 【BZOJ 2673】[Wf2011]Chips Challenge

    题目大意: 传送门 $n*n$的棋盘,有一些位置可以放棋子,有一些已经放了棋子,有一些什么都没有,也不能放,要求放置以后满足:第i行和第i列的棋子数相同,同时每行的棋子数占总数比例小于$\frac{A ...

  6. Bzoj2673 3961: [WF2011]Chips Challenge 费用流

    国际惯例题面:如果我们枚举放几个零件的话,第二个限制很容易解决,但是第一个怎么办?(好的,这么建图不可做)考虑我们枚举每行每列最多放几个零件t,然后计算零件总数sum.这样如果可行的话,则有t*B&l ...

  7. 解题:BZOJ 2673 World Final 2011 Chips Challenge

    题面 数据范围看起来很像网络流诶(滚那 因为限制多而且强,数据范围也不大,我们考虑不直接求答案,而是转化为判定问题 可以发现第二个限制相对好满足,我们直接枚举这个限制就可以.具体来说是枚举所有行中的最 ...

  8. BZOJ2673 [Wf2011]Chips Challenge 费用流 zkw费用流 网络流

    https://darkbzoj.cf/problem/2673 有一个芯片,芯片上有N*N(1≤N≤40)个插槽,可以在里面装零件. 有些插槽不能装零件,有些插槽必须装零件,剩下的插槽随意. 要求装 ...

  9. bzoj3961[WF2011]Chips Challenge

    题意 给出一个n*n的网格,有些格子必须染成黑色,有些格子必须染成白色,其他格子可以染成黑色或者白色.要求最后第i行的黑格子数目等于第i列的黑格子数目,且某一行/列的格子数目不能超过格子总数的A/B. ...

随机推荐

  1. 【小程序】微信小程序iOS苹果报错“协议错误”

    遇到问题 目前正在开发一个小程序,然后苹果真机测试时发现无法授权并提示,errMsg:"request:fail 未能完成该操作.协议错误" 开发环境下测试没问题,安卓机真机测试没 ...

  2. 【PHP】数组按照字母排序

    /** * 将数组按字母A-Z排序 * @return [type] [description] */ private function chartSort($list) { // $user=$th ...

  3. nginx使用用户真实IP做hash(解决经过CND后ip_hash失效问题)

    在nginx中常用的有以下四种负载均衡的算法,分别是:round-robin.ip-hash.least-connected和weighted.当然在实际生产中或许使用最多的就是ip-hash了,一般 ...

  4. 使用亚马逊服务器报错:Signature not yet current: 20190726T070253Z is still later than 20190726T070246Z (20190726T065746Z + 15 min.)时间不同步的解决办法

    1.首先获取亚马逊的时间: $ curl http://s3.amazonaws.com -v 2.更改当前服务器时间,使之与亚马逊时间同步 $ date -s 'xxxx-xx-xx xx:xx:x ...

  5. Qt中的ui文件转换为py文件

    将pyuic5 -o demo.py demo.ui写入ui-py.bat文件(自定义文件),将ui文件与ui-py.bat文件放在同一文件夹,双击.bat文件即可生成.py文件

  6. 『GoLang』面向对象

    我们总结一下前面看到的:Go 没有类,而是松耦合的类型.方法对接口的实现. 面向对象语言最重要的三个方面分别是:封装,继承和多态,在 Go 中它们是怎样表现的呢? Go实现面向对象的两个关键是stru ...

  7. 鸿蒙内核源码分析(信号消费篇) | 谁让CPU连续四次换栈运行 | 百篇博客分析OpenHarmony源码 | v49.04

    百篇博客系列篇.本篇为: v49.xx 鸿蒙内核源码分析(信号消费篇) | 谁让CPU连续四次换栈运行 | 51.c.h .o 进程管理相关篇为: v02.xx 鸿蒙内核源码分析(进程管理篇) | 谁 ...

  8. 【SpringBoot技术专题】「权限校验专区」Shiro整合JWT授权和认证实现

    本章介绍一下常用的认证框架Shiro结合springboot以及集合jwt快速带您开发完成一个认证框架机制. Maven配置依赖 <dependency> <groupId>o ...

  9. C#开发BIMFACE系列40 服务端API之模型集成

    BIMFACE二次开发系列目录     [已更新最新开发文章,点击查看详细] 随着建筑信息化模型技术的发展,越来越多的人选择在云端浏览建筑模型.现阶段的云端模型浏览大多是基于文件级别,一次只可以浏览一 ...

  10. ldirectord

    试想,LVS作为前端负载均衡设备,当后端服务器宕机时,LVS还会把用户请求发送到该服务器上,这对用户体验来说是极其糟糕的,因为用户的请求无法得到处理.那么是否有一种机制,能保证后端服务器的是否正常?或 ...