题面

数据范围看起来很像网络流诶(滚那

因为限制多而且强,数据范围也不大,我们考虑不直接求答案,而是转化为判定问题

可以发现第二个限制相对好满足,我们直接枚举这个限制就可以。具体来说是枚举所有行中的最大值$x$,然后下面那个式子移项就可以得到$a*tot>=b*x$,其中tot表示芯片的总数

然后发现第一个限制还是很强,不好满足。怎么办呢?正难则反,转化成补集的问题:先把所有能安的芯片都安了,然后扣出来合法的答案

那么现在我们要扣掉的芯片尽量少,同时还要先保证扣出来的结果合法,那考虑用最小费用最大流,用最大流的限制使得答案合法,用最小费用求答案

具体来说我们这样建图(下面再解释):

①把原图拆成行和列共n个点

②记录每行每列最多的芯片个数(包括已经有的和空位),从原点向一边连边,另一边向汇点连边(这里为了方便我默认原点向行连,汇点向列连)。容量为芯片个数,费用为零(这个不用解释吧)

③第i行向第i列连容量为我们枚举的答案的边,表示至多留下这些芯片,费用仍然为零

④对于每个空位(x,y),从第x行向第y列连流量为1费用为1的边,表示同时从这一行一列扣掉一个芯片

然后跑最小费用最大流,当且仅当最大流等于芯片的最大总数(包括已经有的和空位))时更新答案,为什么?

因为最小费用最大流会优先保证满流,所以我们③中连的边相当于限制了每行每列的芯片个数一样,就满足了第一个限制,然后扣掉的加上剩下的等于总数才是合法的,所以这时候更新答案

大概就是这样,我觉得这题还是有点意思的=。=

 #include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int B=,N=,M=,inf=1e9;
int mxr[B],mxc[B],mapp[B][B]; char rd[B];
int mflw[N],mcst[N],pren[N],pree[N],queu[N];
int p[N],noww[*M],goal[*M],flow[*M],cost[*M];
int n,a,b,s,t,id,ocp,tot,num,cnt,ans,maxf,minc; queue<int> qs;
void Link(int f,int t,int v,int c)
{
noww[++cnt]=p[f],p[f]=cnt;
goal[cnt]=t,flow[cnt]=v,cost[cnt]=c;
noww[++cnt]=p[t],p[t]=cnt;
goal[cnt]=f,flow[cnt]=,cost[cnt]=-c;
}
void Setit()
{
memset(mxr,,sizeof mxr);
memset(mxc,,sizeof mxc);
ocp=tot=,ans=-,s=n*+,t=s+;
for(int i=;i<=n;i++)
{
scanf("%s",rd+);
for(int j=;j<=n;j++)
{
mapp[i][j]=rd[j],ocp+=rd[j]=='C';
if(rd[j]!='/') mxr[i]++,mxc[j]++,tot++;
}
}
}
void Init(int st,int ed)
{
memset(mflw,0x3f,sizeof mflw);
memset(mcst,0x3f,sizeof mcst);
memset(queu,,sizeof queu),pren[ed]=-;
qs.push(st),queu[st]=true,mcst[st]=;
}
bool SP(int st,int ed)
{
Init(st,ed);
while(!qs.empty())
{
int tn=qs.front();
qs.pop(),queu[tn]=false;
for(int i=p[tn],g;i;i=noww[i])
if(mcst[g=goal[i]]>mcst[tn]+cost[i]&&flow[i])
{
pree[g]=i,pren[g]=tn;
mcst[g]=mcst[tn]+cost[i];
mflw[g]=min(mflw[tn],flow[i]);
if(!queu[g]) qs.push(g),queu[g]=true;
}
}
return ~pren[ed];
}
void MCMF(int st,int ed)
{
while(SP(st,ed))
{
maxf+=mflw[ed],id=ed;
minc+=mflw[ed]*mcst[ed];
while(id!=st)
{
flow[pree[id]]-=mflw[ed];
flow[pree[id]^]+=mflw[ed];
id=pren[id];
}
}
}
int Solve(int x)
{
memset(p,,sizeof p),cnt=,maxf=minc=;
for(int i=;i<=n;i++)
Link(s,i,mxr[i],),Link(i+n,t,mxc[i],),Link(i,i+n,x,);
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(mapp[i][j]=='.') Link(i,j+n,,); MCMF(s,t);
return maxf==tot?(a*(tot-minc)>=b*x?tot-ocp-minc:-):-;
}
int main()
{
while(scanf("%d%d%d",&n,&a,&b)!=EOF)
if(n||a||b)
{
Setit();
for(int i=;i<=n;i++)
ans=max(ans,Solve(i));
printf("Case %d: ",++num);
~ans?printf("%d\n",ans):printf("impossible\n");
}
else break;
return ;
}

解题:BZOJ 2673 World Final 2011 Chips Challenge的更多相关文章

  1. BZOJ 2440 [中山市选2011]完全平方数 | 莫比乌斯函数

    BZOJ 2440 [中山市选2011]完全平方数 | 莫比乌斯函数 题面 找出第k个不是平方数的倍数的数(1不是平方数, \(k \le 10^9\)). 题解 首先二分答案,问题就转化成了求\([ ...

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

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

  3. bzoj 2441 [中山市选2011]小W的问题

    bzoj 2441 [中山市选2011]小W的问题 Description 有一天,小W找了一个笛卡尔坐标系,并在上面选取了N个整点.他发现通过这些整点能够画出很多个"W"出来.具 ...

  4. 【BZOJ 2673】[Wf2011]Chips Challenge

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

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

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

  6. BZOJ 2440 [中山市选2011]完全平方数 (二分 + 莫比乌斯函数)

    2440: [中山市选2011]完全平方数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 4805  Solved: 2325[Submit][Sta ...

  7. BZOJ 2440: [中山市选2011]完全平方数 [容斥原理 莫比乌斯函数]

    2440: [中山市选2011]完全平方数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3028  Solved: 1460[Submit][Sta ...

  8. BZOJ 3721: PA2014 Final Bazarek

    3721: PA2014 Final Bazarek Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 645  Solved: 261[Submit][ ...

  9. [BZOJ 2440] [中山市选2011] 完全平方数 【二分 + 莫比乌斯函数】

    题目链接:BZOJ - 2440 题目分析 首先,通过打表之类的方法可以知道,答案不会超过 2 * k . 那么我们使用二分,对于一个二分的值 x ,求出 [1, x] 之间的可以送出的数有多少个. ...

随机推荐

  1. shell之arp命令

    arp: 显示所有的表项. arp -d address: 删除一个arp表项. arp -s address hw_addr: 设置一个arp表项.   常用参数: -a 使用bsd形式输出.(没有 ...

  2. 【quickhybrid】组件(自定义)API的实现

    前言 前文在API规划时就已经有提到过组件API这个概念,本文将会介绍它的原理以及实现 理解组件API这个概念 quick.ui.xxx quick.page.xxx 在quick hybrid中,A ...

  3. Beta发布—视频展示

    视频链接:http://v.youku.com/v_show/id_XMzE3ODQ0NjIzMg==.html视频简要内容介绍:1.一个小小的logo展示.2.在alpha的基础上,beta发布中增 ...

  4. java怎样把后台值传到前台

    后台代码:if(this.Request["type"]!=null){aaa=this.Request["type"].ToString(); try{bbb ...

  5. Python数据结构练习

    1. 给定列表L,如[2,5,3,8,10,1],对其进行升序排序并输出. 代码: list = [2,5,8,10,1] print(list) list.sort() print(list) 2. ...

  6. json反序列化对象

    这个是同事研究的wcf中中根据type类型反序列化json的示例 /// <summary> /// json转对象 /// </summary> /// <param ...

  7. mvc 路由配置-学习

    MapRoute(RouteCollection, String, String) 映射指定的URL路由. 'Declaration <ExtensionAttribute> _ Publ ...

  8. Head First Java & 构造函数

        java继承中对构造函数是不继承的,只是调用(隐式或显式). ----------------------------------------------------------------- ...

  9. 项目复审—Alpha阶段

    项目复审-Alpha阶段 小组的名字和链接 优 点 缺 点 排名 [别看了你没救队]http://www.cnblogs.com/liaoyujun233/p/9016362.html 此队优点很多, ...

  10. sql update set from 的用法 (转)

    关键字: update set from 下面是这样一个例子: 两个表a.b,想使b中的memo字段值等于a表中对应id的name值     表a:id, name               1   ...