参考: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【最小费用最大流】的更多相关文章

  1. BZOJ 2668 [cqoi2012]交换棋子 | 最小费用最大流

    传送门 BZOJ 2668 题解 同时分别限制流入和流出次数,所以把一个点拆成三个:入点in(x).中间点mi(x).出点ou(x). 如果一个格子x在初始状态是黑点,则连(S, mi(x), 1, ...

  2. BZOJ 1061 志愿者招募(最小费用最大流)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1061 题意:申奥成功后,布布经过不懈努力,终于 成为奥组委下属公司人力资源部门的主管.布 ...

  3. bzoj 1070 [SCOI2007]修车(最小费用最大流)

    1070: [SCOI2007]修车 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 3515  Solved: 1411[Submit][Status] ...

  4. BZOJ 1221: [HNOI2001] 软件开发(最小费用最大流)

    不知道为什么这么慢.... 费用流,拆点.... --------------------------------------------------------------------------- ...

  5. bzoj 3171: [Tjoi2013]循环格 最小费用最大流

    题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=3171 题解: 首先我们很容易发现一个结论: 出现完美循环当且仅当所有点的出入度均为1 所 ...

  6. bzoj 1070: [SCOI2007]修车【最小费用最大流】

    一开始从客人角度想的,怎么建都不对 从一个修车工所接待的所有顾客花费的总时间来看,设一共有x个人,那么第一个修的对总时间的贡献是x*w1,第二个是(x-1)*w2-以此类推.所以把第i个修车工拆成n组 ...

  7. BZOJ 1449 球队收益(最小费用最大流)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1449 题意: 思路:首先,我们假设后面的M场比赛两方都是输的,即初始时的lose[i]再 ...

  8. BZOJ 1449: [JSOI2009]球队收益 最小费用最大流 网络流

    https://www.lydsy.com/JudgeOnline/problem.php?id=1449 给每条路加上一个权值,每条路的费用是这条路的流量*权值,求最大流的最小费用. 每次spfa记 ...

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

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

随机推荐

  1. 50个必备的实用jQuery代码段(转载)

    本文会给你们展示50个jquery代码片段,这些代码能够给你的javascript项目提供帮助.其中的一些代码段是从jQuery1.4.2才开始支持的做法,另一些则是真正有用的函数或方法,他们能够帮助 ...

  2. Milking Time---poj3616

    Description Bessie is such a hard-working cow. In fact, she is so focused on maximizing her producti ...

  3. linux修改PS1,自定义命令提示符样式

    目录 参数说明 修改颜色 linux默认的命令提示符是这样的: 白色的,如果当前执行的命令很多的话,一整块屏幕上全是一堆输出信息,上一条命令在哪?我刚输入的命令在哪?找的头晕.有没有办法可以修改命令提 ...

  4. maven pom.xml文件介绍

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...

  5. Java的对象和类

    以下内容引用自http://wiki.jikexueyuan.com/project/java/object-classes.html: 一.概述 Java是一种面向对象的语言.作为一种具有面向对象特 ...

  6. 【OPPO主题制作系列 - 01】-- 写个小工具自动打包Theme文件

    参考OPPO主题设计师站: http://dev.theme.oppomobile.com/user/user_start 想要打包成Theme文件,必须把需要打包的文件夹拖到oppo-themepa ...

  7. eclipse提速03 - 禁用动画

  8. 微信接入登录功能access_token流程记录

    提示:只有认证过的订阅号或者服务号才能获取access_token. 1.app微信登录第一步是,app调起来微信客户端,通过app端的配置,引入一个微信类库, 2.授权成功后,微信会返回你一个cod ...

  9. 系统性能不够原因可能是cpu不够,内存不够等等

    1.Linux系统可以通过top命令查看系统的CPU.内存.运行时间.交换分区.执行的线程等信息. 通过top命令可以有效的发现系统的缺陷出在哪里.是内存不够.CPU处理能力不够.IO读写过高. 2. ...

  10. 拷贝地图 CopyAndOverwriteMap()

    private void CopyAndOverwriteMap() { //Get IObjectCopy interface IObjectCopy objectCopy = new Object ...