bzoj 3961: [WF2011]Chips Challenge【最小费用最大流】
参考:https://blog.csdn.net/Quack_quack/article/details/50554032
神建图系列
首先把问题转为全填上,最少扣下来几个能符合条件
先考虑第2个条件,枚举f为一个每行/列最大剩几个,然后记录一下每行列的零件个数(包括填上的)
然后建图
s向所有行连流量为这行的零件数的边,所有列向t连流量为这列的零件数的边,i行向i列连流量为f的边,表示这行列最多流f,每个能扣下来的(i,j)连i行j列,因为这个要尽量小而且需要计数,所以附加上1的价值(别的边都为0),然后跑最小费用最大流,判合法有两个条件:1,总流量为总零件数(满流),因为选和不选都能在图上流过去;2,fb<=(sum-val)a
以及我之前写的费用流板子都是错的???
而且这个好像不能动态加流量,只能枚举着重建图。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=105,inf=1e9;
int n,a,b,h[N],cnt,s,t,flo,val,dis[N],fr[N];
char p[N][N];
bool v[N],vis[N];
struct qwe
{
int ne,no,to,va,c;
}e[N*N];
void add(int u,int v,int w,int c)
{
cnt++;
e[cnt].ne=h[u];
e[cnt].no=u;
e[cnt].to=v;
e[cnt].va=w;
e[cnt].c=c;
h[u]=cnt;
}
void ins(int u,int v,int w,int c)
{//cerr<<u<<" "<<v<<" "<<w<<" "<<c<<endl;
add(u,v,w,c);
add(v,u,0,-c);
}
bool spfa()
{
memset(v,0,sizeof(v));
queue<int>q;
for(int i=s;i<=t;i++)
dis[i]=inf;
dis[s]=0;
v[s]=1;
q.push(s);
while(!q.empty())
{
int u=q.front();//cerr<<u<<endl
q.pop();
v[u]=0;
for(int i=h[u];i;i=e[i].ne)
if(e[i].va>0&&dis[e[i].to]>dis[u]+e[i].c)
{
dis[e[i].to]=dis[u]+e[i].c;
fr[e[i].to]=i;
if(!v[e[i].to])
v[e[i].to]=1,q.push(e[i].to);
}
}
return dis[t]!=inf;
}
// void mcf()
// {
// int x=inf;
// for(int i=fr[t];i;i=fr[e[i].no])
// x=min(x,e[i].va);//,cerr<<e[i].to<<" ";cerr<<endl;
// flo+=x;
// for(int i=fr[t];i;i=fr[e[i].no])
// {
// e[i].va-=x;
// e[i^1].va+=x;
// val+=x*e[i].c;
// }
// }
inline int dfs(int u,int f)
{
if(u==t) return f;
int us=0;
vis[u]=1;
for(int i=h[u];i&&us<f;i=e[i].ne)
if(e[i].va>0&&!vis[e[i].to]&&dis[e[i].to]==dis[u]+e[i].c)
{
int t=dfs(e[i].to,min(f,e[i].va));
us+=t;
val+=e[i].c*t ,
e[i].va-=t,e[i^1].va+=t;
}
if(!us)
dis[u]=inf;
vis[u]=0;
return us;
}
int main()
{
for(int cas=1;;cas++)
{
scanf("%d%d%d",&n,&a,&b);
if(n+a+b==0)
break;
int sum=0,con=0,r[45],c[45],ans=-1;
cnt=1,s=0,t=2*n+1,flo=0,val=0;
memset(h,0,sizeof(h));
memset(r,0,sizeof(r));
memset(c,0,sizeof(c));
for(int i=1;i<=n;i++)
{
scanf("%s",p[i]+1);
for(int j=1;j<=n;j++)
if(p[i][j]!='/')
{
sum++,r[i]++,c[j]++;
if(p[i][j]=='C')
con++;
// else
// ins(i,j+n,1,1);
}
}
// for(int i=1;i<=n;i++)
// ins(s,i,r[i],0),ins(i+n,t,c[i],0);
// int st=cnt+1;
// for(int i=1;i<=n;i++)
// ins(i,i+n,0,0);
// while(spfa())
// mcf();
//cerr<<flo<<" "<<val<<endl;
// if(flo==sum&&(sum-val)*a>=0)
// ans=max(ans,sum-val);
// for(int f=1;f<=n;f++)
// {
// for(int i=st;i<=cnt;i+=2)
// e[i].va++;
// while(spfa())
// mcf();
// cerr<<flo<<" "<<val<<endl;
// if(flo==sum&&(sum-val)*a>=f*b)
// ans=max(ans,sum-val);
// }
for(int f=0;f<=n;++f)
{
memset(h,0,sizeof h);
flo=val=s=0;cnt=1;
t=n*2+1;
for(int i=1;i<=n;++i)
{
ins(s,i,r[i],0);
ins(i+n,t,c[i],0);
ins(i,i+n,f,0);
for(int j=1;j<=n;++j)
if(p[i][j]=='.')
ins(i,j+n,1,1);
}
while(spfa())
flo+=dfs(s,inf);
if(flo==sum&&f*b<=(sum-val)*a)
ans=max(ans,sum-val);
}
printf("Case %d: ",cas);
if(ans==-1)
puts("impossible");
else
printf("%d\n",ans-con);
}
return 0;
}
/*
2 1 1
/.
//
2 50 100
/.
C/
0 0 0
*/
bzoj 3961: [WF2011]Chips Challenge【最小费用最大流】的更多相关文章
- BZOJ 2668 [cqoi2012]交换棋子 | 最小费用最大流
传送门 BZOJ 2668 题解 同时分别限制流入和流出次数,所以把一个点拆成三个:入点in(x).中间点mi(x).出点ou(x). 如果一个格子x在初始状态是黑点,则连(S, mi(x), 1, ...
- BZOJ 1061 志愿者招募(最小费用最大流)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1061 题意:申奥成功后,布布经过不懈努力,终于 成为奥组委下属公司人力资源部门的主管.布 ...
- bzoj 1070 [SCOI2007]修车(最小费用最大流)
1070: [SCOI2007]修车 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3515 Solved: 1411[Submit][Status] ...
- BZOJ 1221: [HNOI2001] 软件开发(最小费用最大流)
不知道为什么这么慢.... 费用流,拆点.... --------------------------------------------------------------------------- ...
- bzoj 3171: [Tjoi2013]循环格 最小费用最大流
题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=3171 题解: 首先我们很容易发现一个结论: 出现完美循环当且仅当所有点的出入度均为1 所 ...
- bzoj 1070: [SCOI2007]修车【最小费用最大流】
一开始从客人角度想的,怎么建都不对 从一个修车工所接待的所有顾客花费的总时间来看,设一共有x个人,那么第一个修的对总时间的贡献是x*w1,第二个是(x-1)*w2-以此类推.所以把第i个修车工拆成n组 ...
- BZOJ 1449 球队收益(最小费用最大流)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1449 题意: 思路:首先,我们假设后面的M场比赛两方都是输的,即初始时的lose[i]再 ...
- BZOJ 1449: [JSOI2009]球队收益 最小费用最大流 网络流
https://www.lydsy.com/JudgeOnline/problem.php?id=1449 给每条路加上一个权值,每条路的费用是这条路的流量*权值,求最大流的最小费用. 每次spfa记 ...
- Bzoj2673 3961: [WF2011]Chips Challenge 费用流
国际惯例题面:如果我们枚举放几个零件的话,第二个限制很容易解决,但是第一个怎么办?(好的,这么建图不可做)考虑我们枚举每行每列最多放几个零件t,然后计算零件总数sum.这样如果可行的话,则有t*B&l ...
随机推荐
- 一份关于webpack2和模块打包的新手指南(二)
插件 我们已经看到一个内置的webpack插件的例子,在npm run build脚本中调用的webpack -p命令就是使用webpack附带的UglifyJsPlugin插件以生产模式压缩打包文件 ...
- Hibernate学习笔记(四)
我是从b站视频上学习的hibernate框架,其中有很多和当前版本不符合之处,我在笔记中进行了修改以下是b站视频地址:https://www.bilibili.com/video/av14626440 ...
- PHP移植
1. 首先交叉编译zlib. CC=arm-linux-gcc ./configure --sahred --prefix=/usr/local/arm/3.4.1/arm-linux make&am ...
- WebLogic"域"的概念
WebLogic Server中的域是逻辑上相关的一组 WebLogic Server 资源,可以作为一个单元进行管理.一个域中包含一台或多台 WebLogic Server,也可以包含 WebLog ...
- Go --- 设计模式(工厂模式)
简易工厂主要是用来解决对象“创建”的问题.以下的例子取自<大话设计模式>中第一章,实现一个可扩展的“计算器”.当增加新的功能时,并不需改动原来已经实现的算法.由于是简易工厂,所以我们还是需 ...
- L0、L1与L2范数
监督机器学习问题无非就是“minimize your error while regularizing your parameters”,也就是在正则化参数的同时最小化误差.最小化误差是为了让我们的模 ...
- 【stl学习笔记】vector
vector是定义于namespace std内的template: namespace std { template<class T, class Allocator = allocator& ...
- Dom对象的经常用法
Dom对象的经常用法: (1)getElementById() 查询给定ID属性值的元素,返回该元素的元素节点 1. 查询给定ID属性值的元素,返回该元素的元素节点.也称为元素对象. ...
- iOS iOS8中 问题"registerForRemoteNotificationTypes: is not supported in iOS 8.0 and later" 解决方式
问题重述: iOS 8中改变了通知注冊的方式,假设App须要同一时候支持iOS 7 和 8 的话,须要首先检查selector. 解决方式:在Xcode 6中 - (BOOL)application: ...
- axis client tomcat jsp调用最少jar
tomcat调用和main方法调用不同在于引入的jar不一样.tomcat引入的jar是全部lib以下的jar包,main是project引入的jar.假设直接进行公布lib下的全部jar都会引入到p ...