参考: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. P1194 买礼物 洛谷

    https://www.luogu.org/problem/show?pid=1194 题目描述 又到了一年一度的明明生日了,明明想要买B样东西,巧的是,这B样东西价格都是A元. 但是,商店老板说最近 ...

  2. POJ 2346 【DP】

    题意: 给一个正的不大于10的偶数n,求n个数字组成的数字串前n/2位和后n/2位的和相等的个数. 思路: dp[i][j]由i位数组成的和为j的数字串的个数. dp[i][j]+=dp[i-1][j ...

  3. Exchanger使用

    Exchanger使用

  4. [Javascript] Understanding the .constructor property on JavaScript Objects

    Constructor functions hold an interesting purpose in JavaScript. Unlike in classical languages, they ...

  5. linuxc线程信号-pthread_cond_wait理解

    pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t*mutex)函数 传入的參数mutex用于保护条件,由于我们在调用pthread_con ...

  6. Java基础实例

    打印等腰三角形代码 public class ForForTest{ public static void main(String []args){ for(int x=0;x<5;x++){ ...

  7. js和jquery实现回到顶层

    js <!DOCTYPE html> <html> <head> <title>返回顶部</title> <style> bod ...

  8. 图像配准建立仿射变换模型并用RANSAC算法评估

    当初选方向时就由于从小几何就不好.缺乏空间想像能力才没有选择摄影測量方向而是选择了GIS. 昨天同学找我帮他做图像匹配.这我哪里懂啊,无奈我是一个别人有求于我,总是不好意思开口拒绝的人.于是乎就看着他 ...

  9. Spring中AOP的使用

    问题:什么是AOP? 答:AOP基本概念:Aspect-Oriented Programming,面向方面编程的简称,Aspect是一种新的模块化机制.用来描写叙述分散在对象.类或方法中的横切关注点( ...

  10. 大学生程序设计邀请赛(华东师范大学)B. 分词 DP

    B. 分词   有一句句子因为粘贴的时候出现了一点问题空格全部丢失了.现在给一本字典,每个词都对应这个词出现的频率(每十亿).根据这个频率,我们可以根据下面的公式算出这个词带来的收益 P(word): ...