Chips Challenge

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 96    Accepted Submission(s): 33

Problem Description
A prominent microprocessor company has enlisted your help to lay out some interchangeable components (widgets) on some of their computer chips. Each chip’s design is an N×N square of slots. One slot can hold a single component, and you are to try to fit in as many widgets as possible.

Modern processor designs are complex, of course. You unfortunately have several restrictions:

    • Some of the slots are disabled.
    • Some of the slots are already occupied by other components and cannot be used for widgets.
    • There are sibling memory buses connected to the horizontal and vertical edges of the chip and their bandwidth loads need to match. As such, there must be exactly as many components in the first row as in the first column, exactly as many in the second row as in the second column, and so on. Component counts include both the components already specified on the chip and the added widgets.
    • Similarly, the power supply is connected at the end of each row and column. To avoid hot spots, any given row or column must have no more than A=B of the total components on the chip for a given A and B.

A specification for a chip is N lines of N characters, where ‘.’ indicates an open slot, ‘/’ indicates a disabled slot, and ‘C’ indicates a slot already occupied by a component. For example:

CC/..
././/
..C.C
/.C..
/./C/

If no more than 3/10 of the components may be in any one row or column, the maximum number of widgets that can be added to this 5 × 5 chip is 7. A possible arrangement is below, where ‘W’ indicates a widget added in an open slot.

CC/W.
W/W//
W.C.C
/.CWW
/W/C/

 
Input
The input consists of several test cases. Each case starts with a line containing three integers: The size of the chip N (1 <= N <= 40), and A and B (1 <= B <= 1000, 0 <= A <= B) as described above. Each of the following N lines contains N characters describing the slots, one of ‘.’, ‘/’ or ‘C’, as described above.
The last test case is followed by a line containing three zeros.
 
Output
For each test case, display a single line beginning with the case number. If there is a solution, display the maximum number of widgets that can be added to the chip. Display “impossible” if there is no solution.
Follow the format of the sample output.
 
Sample Input
2 1 1
/.
//
2 50 100
/.
C/
2 100 100
./
C.
5 3 10
CC/..
././/
..C.C
/.C..
/./C/
5 2 10
CC/..
././/
..C.C
/.C..
/./C/
0 0 0
 
Sample Output
Case 1: 0
Case 2: 1
Case 3: impossible
Case 4: 7
Case 5: impossible
 
Source
 
Recommend

//EK 1825ms
#include<cstdio>
#include<cstring>
#include<iostream>
#define m(s) memset(s,0,sizeof s);
#define EF if(ch==EOF) return x;
using namespace std;
const int N=;
const int M=N*N<<;
struct edge{int v,next,cap,cost;}e[M];int tot=,head[N];
int n,cas,A,B,ans,S,T,rd[N],cd[N],dis[N],pre[N],q[N+M];bool vis[N];
int sum,hav,maxflow,maxcost;char s[N][N];
inline int read(){
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;EF;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
void add(int x,int y,int z,int cost=){
e[++tot].v=y;e[tot].cap=z;e[tot].cost=cost;e[tot].next=head[x];head[x]=tot;
e[++tot].v=x;e[tot].cap=;e[tot].cost=-cost;e[tot].next=head[y];head[y]=tot;
}
bool spfa(){
memset(vis,,sizeof vis);
memset(dis,0x3f,sizeof dis);
unsigned short h=,t=;q[t]=S;dis[S]=;vis[S]=;
while(h!=t){
int x=q[++h];vis[x]=;
for(int i=head[x];i;i=e[i].next){
if(e[i].cap&&dis[e[i].v]>dis[x]+e[i].cost){
dis[e[i].v]=dis[x]+e[i].cost;
pre[e[i].v]=i;
if(!vis[e[i].v]){
vis[e[i].v]=;
q[++t]=e[i].v;
}
}
}
}
return dis[T]<0x3f3f3f3f;
}
void augment(){
int flow=0x3f3f3f3f;
for(int i=T;i!=S;i=e[pre[i]^].v) flow=min(flow,e[pre[i]].cap);
for(int i=T;i!=S;i=e[pre[i]^].v){
e[pre[i]].cap-=flow;
e[pre[i]^].cap+=flow;
}
maxflow+=flow;
maxcost+=dis[T]*flow;
}
int main(){
while(){
n=read();A=read();B=read();
if(!n) return ;
printf("Case %d: ",++cas);
S=,T=n<<|;
sum=;hav=;ans=-;m(rd);m(cd);
for(int i=;i<=n;i++){
scanf("%s",s[i]+);
for(int j=;j<=n;j++){
if(s[i][j]=='C'||s[i][j]=='.'){
sum++;cd[i]++,rd[j]++;
if(s[i][j]=='C') hav++;
}
}
}
for(int maxt=;maxt<=n;maxt++){
tot=;m(head);
for(int i=;i<=n;i++){
add(S,i,cd[i]);add(i,i+n,maxt);add(i+n,T,rd[i]);
for(int j=;j<=n;j++){
if(s[i][j]=='.') add(i,j+n,,);
}
}
maxflow=maxcost=;
while(spfa()) augment();
if(maxflow==sum&&(maxflow-maxcost)*A>=maxt*B) ans=max(ans,maxflow-maxcost);
}
if(~ans) printf("%d\n",ans-hav);
else puts("impossible");
}
return ;
}
//zkw 280ms
#include<cstdio>
#include<cstring>
#include<iostream>
#define m(s) memset(s,0,sizeof s);
#define EF if(ch==EOF) return x;
using namespace std;
const int N=;
const int M=N*N<<;
struct edge{int v,next,cap,cost;}e[M];int tot=,head[N];
int n,cas,A,B,ans,S,T,rd[N],cd[N],dis[N],pre[N],q[N+M],tim,mark[N];bool vis[N];
int sum,hav,maxflow,maxcost;char s[N][N];
inline int read(){
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;EF;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
inline void add(int x,int y,int z,int cost=){
e[++tot].v=y;e[tot].cap=z;e[tot].cost=cost;e[tot].next=head[x];head[x]=tot;
e[++tot].v=x;e[tot].cap=;e[tot].cost=-cost;e[tot].next=head[y];head[y]=tot;
}
inline bool spfa(){
memset(vis,,sizeof vis);
memset(dis,0x3f,sizeof dis);
unsigned short h=,t=;q[t]=S;dis[S]=;vis[S]=;
while(h!=t){
int x=q[++h];vis[x]=;
for(int i=head[x];i;i=e[i].next){
if(e[i].cap&&dis[e[i].v]>dis[x]+e[i].cost){
dis[e[i].v]=dis[x]+e[i].cost;
pre[e[i].v]=i;
if(!vis[e[i].v]){
vis[e[i].v]=;
q[++t]=e[i].v;
}
}
}
}
return dis[T]<0x3f3f3f3f;
}
int dfs(int x,int f){
if(x==T) return f;
int used=,t;
mark[x]=tim;
for(int i=head[x];i;i=e[i].next){
if((mark[e[i].v]^tim)&&e[i].cap&&dis[e[i].v]==dis[x]+e[i].cost){
t=dfs(e[i].v,min(f,e[i].cap));
e[i].cap-=t;e[i^].cap+=t;
used+=t;f-=t;
if(!f) return used;
}
}
if(!used) dis[x]=-;
return used;
}
inline void zkw(){
int flow=;
while(spfa()){
while(tim++,flow=dfs(S,0x3f3f3f3f)){
maxflow+=flow;
maxcost+=dis[T]*flow;
}
}
}
int main(){
while(){
n=read();A=read();B=read();
if(!n) return ;
printf("Case %d: ",++cas);
S=,T=n<<|;
sum=;hav=;ans=-;m(rd);m(cd);
for(int i=;i<=n;i++){
scanf("%s",s[i]+);
for(int j=;j<=n;j++){
if(s[i][j]=='C'||s[i][j]=='.'){
sum++;cd[i]++,rd[j]++;
if(s[i][j]=='C') hav++;
}
}
}
for(int maxt=;maxt<=n;maxt++){
tot=;m(head);
for(int i=;i<=n;i++){
add(S,i,cd[i]);add(i,i+n,maxt);add(i+n,T,rd[i]);
for(int j=;j<=n;j++){
if(s[i][j]=='.') add(i,j+n,,);
}
}
maxflow=maxcost=;
zkw();
if(maxflow==sum&&(maxflow-maxcost)*A>=maxt*B) ans=max(ans,maxflow-maxcost);
}
if(~ans) printf("%d\n",ans-hav);
else puts("impossible");
}
return ;
}

[2011WorldFinal]Chips Challenge[流量平衡]的更多相关文章

  1. bzoj3961[WF2011]Chips Challenge

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

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

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

  3. 【BZOJ 2673】[Wf2011]Chips Challenge

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

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

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

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

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

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

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

  7. [Wf2011]Chips Challenge

    两个条件都不太好处理 每行放置的个数实际很小,枚举最多放x 但还是不好放 考虑所有位置先都放上,然后删除最少使得合法 为了凑所有的位置都考虑到,把它当最大流 但是删除最少,所以最小费用 行列相关,左行 ...

  8. bzoj 3961: [WF2011]Chips Challenge【最小费用最大流】

    参考:https://blog.csdn.net/Quack_quack/article/details/50554032 神建图系列 首先把问题转为全填上,最少扣下来几个能符合条件 先考虑第2个条件 ...

  9. 【题解】uva1104 chips challenge

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

随机推荐

  1. android 上下左右手势判断 根据别人的改的

    GestureUtils.java package com.gesture; import android.content.Context;import android.util.DisplayMet ...

  2. sim800L调试问题

    SIM800L默认上电开机,若此时没有把rst和pwk引脚提前设置好,SIM800l会使stm32进入硬件中断(这可能是因为方面电源的原因导致的),同时sim800L开机后需要一定的时间稳定下来,建议 ...

  3. 转 redis使用场景 简介

    Redis实战(五) 聊聊Redis使用场景 发表于 2016-11-21 | 数据存储 | Redis 文章目录 1. 使用场景说明 1.1. 计数器 1.2. 排行榜 1.3. 用于存储时间戳 1 ...

  4. Spring Cloud(八):分布式配置中心服务化和高可用

    在前两篇的介绍中,客户端都是直接调用配置中心的server端来获取配置文件信息.这样就存在了一个问题,客户端和服务端的耦合性太高,如果server端要做集群,客户端只能通过原始的方式来路由,serve ...

  5. Atititjs javascript异常处理机制与java异常的转换.js exception process

    Atititjs javascript异常处理机制与java异常的转换.js exception process 1. javascript异常处理机制 Throw str Not throw err ...

  6. python内置函数之print()

    定义:将值打印到一个流对象,或者默认打印到sys.stdout. 语法: print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=Fal ...

  7. Qt5中的QtGui

    我在学习Qt查看Qt Creater提供的例子时,遇到了一个小问题.就是明明在代码中包含了QtGui,然而编译的时候还是提示找不到QLabel的定义,以及其他一些类的定义,但是这是官方提供的文档的啊, ...

  8. (转)maven3.3.9编译oozie4.3.0

    1.Java版本1.8 [root@sht-sgmhadoopdn-04 app]# java -versionjava version "1.8.0_66"Java(TM) SE ...

  9. SSIS 自测题-控制流控件类

    说明:以下是自己的理解答案,不是标准的答案,如有不妥烦请指出.         有些题目暂时没有答案,有知道的请留言,互相学习,一起进步. 62.描述一下 Execute SQL Task 的作用,在 ...

  10. java---堆、栈、常量池的存储数据

    说到Java中堆.栈和常量池,首先还是看看他们各自存放的数据类型吧! 栈: Java的JVM的内存可分为3个区:堆(heap).栈(stack)和方法区(method)也叫静态存储区. 堆区:(存放所 ...