解题:BZOJ 2673 World Final 2011 Chips Challenge
数据范围看起来很像网络流诶(滚那
因为限制多而且强,数据范围也不大,我们考虑不直接求答案,而是转化为判定问题
可以发现第二个限制相对好满足,我们直接枚举这个限制就可以。具体来说是枚举所有行中的最大值$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的更多相关文章
- BZOJ 2440 [中山市选2011]完全平方数 | 莫比乌斯函数
BZOJ 2440 [中山市选2011]完全平方数 | 莫比乌斯函数 题面 找出第k个不是平方数的倍数的数(1不是平方数, \(k \le 10^9\)). 题解 首先二分答案,问题就转化成了求\([ ...
- [2011WorldFinal]Chips Challenge[流量平衡]
Chips Challenge Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- bzoj 2441 [中山市选2011]小W的问题
bzoj 2441 [中山市选2011]小W的问题 Description 有一天,小W找了一个笛卡尔坐标系,并在上面选取了N个整点.他发现通过这些整点能够画出很多个"W"出来.具 ...
- 【BZOJ 2673】[Wf2011]Chips Challenge
题目大意: 传送门 $n*n$的棋盘,有一些位置可以放棋子,有一些已经放了棋子,有一些什么都没有,也不能放,要求放置以后满足:第i行和第i列的棋子数相同,同时每行的棋子数占总数比例小于$\frac{A ...
- bzoj 3961: [WF2011]Chips Challenge【最小费用最大流】
参考:https://blog.csdn.net/Quack_quack/article/details/50554032 神建图系列 首先把问题转为全填上,最少扣下来几个能符合条件 先考虑第2个条件 ...
- BZOJ 2440 [中山市选2011]完全平方数 (二分 + 莫比乌斯函数)
2440: [中山市选2011]完全平方数 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 4805 Solved: 2325[Submit][Sta ...
- BZOJ 2440: [中山市选2011]完全平方数 [容斥原理 莫比乌斯函数]
2440: [中山市选2011]完全平方数 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3028 Solved: 1460[Submit][Sta ...
- BZOJ 3721: PA2014 Final Bazarek
3721: PA2014 Final Bazarek Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 645 Solved: 261[Submit][ ...
- [BZOJ 2440] [中山市选2011] 完全平方数 【二分 + 莫比乌斯函数】
题目链接:BZOJ - 2440 题目分析 首先,通过打表之类的方法可以知道,答案不会超过 2 * k . 那么我们使用二分,对于一个二分的值 x ,求出 [1, x] 之间的可以送出的数有多少个. ...
随机推荐
- Hyperledger Fabric Ledger——账本总账
Ledger Ledger(账本)即所有的state transitions(状态切换),是有序且不可篡改的.state transitions(状态切换)是由参与方提交的chaincode(智能合约 ...
- ossec安装
安装 安装要求 对于Unix系统来说,OSSEC只需要GNU的make.gcc和libc.推荐使用OpenSSL,但仅属于一个可选项.而且,通常您只需在一个系统上做编译操作,然后将二进制程序复制到其他 ...
- 转载---LIBRARY_PATH和LD_LIBRARY_PATH环境变量的区别
总是分不太清楚LIBRARY_PATH和LD_LIBRARY_PATH环境变量的区别,每次都是现查一下,转载到这里,备忘... 转载自:https://www.cnblogs.com/panfeng4 ...
- 在写ssh项目时浏览器页面出现http status 404 – not found
HTTP Status 404 - /streetManager/index.jsp type Status report message /streetManager/index.jsp descr ...
- Task 4.4二维环形数组求最大子矩阵之和
任务: (1)输入一个二维整形数组,数组里有正数也有负数. (2)二维数组首尾相接,象个一条首尾相接带子一样. (3)数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. (4)求所有子数 ...
- Hibernate利用纯sql
String hql = "select * from shop where shop.strid in(select strid from moneythreeshop where mon ...
- WebGL学习笔记(二)
目录 绘制多个顶点 使用缓冲区对象 类型化数组 使用drawArrays()函数绘制图形 图形的移动 图形的旋转 图形的缩放 绘制多个顶点 使用缓冲区对象 创建缓冲区对象 var vertexBuff ...
- 微信小程序Mustache语法
小程序开发的wxml里,用到了Mustache语法.所以,非常有必要把Mustache研究下. 什么是Mustache?Mustache是一个logic-less(轻逻辑)模板解析引擎,它是为了使用户 ...
- \0 的ASCII码值是多少
\0 的ASCII码值是多少 #include<iostream> using namespace std; void main() { char c = '\0'; cout<&l ...
- 字符串经过base64编码后的长度与原字符串的长度是什么关系呀?
beforeEncode为Encode之前的字符串 那么Encode后的字符串长度为: 1.如果beforeEncode.length()是3的整数倍,那么长度为 (beforeEncode.len ...