题意:N个人,F种食物,D种饮料,给定每种食物和饮料的量。每个人有自己喜欢的食物和饮料,如果得到自己喜欢的食物和饮料才能得到满足。求最大满足的人数。

分析:如果只是简单地N个人选择F种食物的话可以用二分图匹配来完成,但是该题种一个人要选择两样东西。

采取以下操作建图:

  增加源点和汇点,源点与F个食物相连,每条弧流量为第i种食物的数量;D个食物与汇点相连,每条弧流量为其数量。

  所以将N个人拆成两个点,对应两点之间连一条边,流量为1。

然后跑出最大流就是答案。

#include<bits/stdc++.h>
using namespace std;
#define captype int
const int MAXN = ;
const int MAXM = ;
const int INF = <<;
struct EDGE{
int to,next;
captype cap;
} edg[MAXM];
int eid,head[MAXN];
int gap[MAXN];
int dis[MAXN];
int cur[MAXN];
int pre[MAXN]; void init(){
eid=;
memset(head,-,sizeof(head));
}
void AddEdge(int u,int v,captype c,captype rc=){
edg[eid].to=v; edg[eid].next=head[u];
edg[eid].cap=c; head[u]=eid++;
edg[eid].to=u; edg[eid].next=head[v];
edg[eid].cap=rc; head[v]=eid++;
}
captype maxFlow_sap(int sNode,int eNode, int n){//n是包括源点和汇点的总点个数,这个一定要注意
memset(gap,,sizeof(gap));
memset(dis,,sizeof(dis));
memcpy(cur,head,sizeof(head));
pre[sNode] = -;
gap[]=n;
captype ans=;
int u=sNode;
while(dis[sNode]<n){
if(u==eNode){
captype Min=INF ;
int inser;
for(int i=pre[u]; i!=-; i=pre[edg[i^].to])
if(Min>edg[i].cap){
Min=edg[i].cap;
inser=i;
}
for(int i=pre[u]; i!=-; i=pre[edg[i^].to]){
edg[i].cap-=Min;
edg[i^].cap+=Min;
}
ans+=Min;
u=edg[inser^].to;
continue;
}
bool flag = false;
int v;
for(int i=cur[u]; i!=-; i=edg[i].next){
v=edg[i].to;
if(edg[i].cap> && dis[u]==dis[v]+){
flag=true;
cur[u]=pre[v]=i;
break;
}
}
if(flag){
u=v;
continue;
}
int Mind= n;
for(int i=head[u]; i!=-; i=edg[i].next)
if(edg[i].cap> && Mind>dis[edg[i].to]){
Mind=dis[edg[i].to];
cur[u]=i;
}
gap[dis[u]]--;
if(gap[dis[u]]==) return ans;
dis[u]=Mind+;
gap[dis[u]]++;
if(u!=sNode) u=edg[pre[u]^].to; //退一条边
}
return ans;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int S,T,N,M,F,D,u,v,tmp;
while(scanf("%d%d%d",&N,&F,&D)==){
S=,T=*N+F+D+; //源点,汇点
init();
for(int i=;i<=F;++i){
scanf("%d",&tmp);
AddEdge(S,i,tmp);
}
for(int i=;i<=D;++i){
scanf("%d",&tmp);
AddEdge(F+N*+i,T,tmp);
}
for(int i=;i<=N;++i){
AddEdge(i+F,i+F+N,);
char op[MAXN];
scanf("%s",op);
for(int j=;j<=F;++j){
if(op[j-]=='Y') AddEdge(j,i+F,);
}
}
for(int i=;i<=N;++i){
char op[MAXN];
scanf("%s",op);
for(int j=;j<=D;++j){
if(op[j-]=='Y') AddEdge(F+N+i,F+N*+j,);
}
}
printf("%d\n",maxFlow_sap(S,T,T+));
}
return ;
}

  

HDU 4292 Food (拆点最大流)的更多相关文章

  1. Food HDU - 4292 网络流 拆点建图

    http://acm.hdu.edu.cn/showproblem.php?pid=4292 给一些人想要的食物和饮料,和你拥有的数量,问最多多少人可以同时获得一份食物和一份饮料 写的时候一共用了2种 ...

  2. HDU 4292:Food(最大流)

    http://acm.hdu.edu.cn/showproblem.php?pid=4292 题意:和奶牛一题差不多,只不过每种食物可以有多种. 思路:因为食物多种,所以源点和汇点的容量要改下.还有D ...

  3. HDU 4292 Food (网络流,最大流)

    HDU 4292 Food (网络流,最大流) Description You, a part-time dining service worker in your college's dining ...

  4. Control(拆点+最大流)

    Control http://acm.hdu.edu.cn/showproblem.php?pid=4289 Time Limit: 2000/1000 MS (Java/Others)    Mem ...

  5. hdu4289 最小割最大流 (拆点最大流)

    最小割最大流定理:(参考刘汝佳p369)增广路算法结束时,令已标号结点(a[u]>0的结点)集合为S,其他结点集合为T=V-S,则(S,T)是图的s-t最小割. Problem Descript ...

  6. HDU 2098 分拆素数和

    HDU 2098 分拆素数和 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768K (Java/Others) [题目描述 ...

  7. HDU 3549 Flow Problem(最大流)

    HDU 3549 Flow Problem(最大流) Time Limit: 5000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/ ...

  8. HDU 2098 分拆素数和(素数)

    HDU 2098 分拆素数和(素数) http://acm.hdu.edu.cn/showproblem.php?pid=2098 题意: 给你一个偶数,问你这个偶数有多少种方式能由两个不同的素数构成 ...

  9. BZOJ 1877 晨跑 拆点费用流

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1877 题目大意: Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧 ...

随机推荐

  1. .net 编译原理

    这听起来像是个非常高大上的名字,上学的时候我们学过的编译原理或者编译技术实际上是在讲如何将高级程序语言如C++编译为计算机可以理解的汇编语言,这里说的编译原理只是想说明在.NET的世界里编译这件事儿和 ...

  2. ASP.NET控件属性大全

    ASP.NET控件属性大全 DataGridView 控件DataGridView 控件提供用来显示数据的可自定义表.使用 DataGridView 类,可以自定义单元格.行.列和边框. 注意Data ...

  3. C语言 函数指针一(函数指针的定义)

    //函数指针 #include<stdio.h> #include<stdlib.h> #include<string.h> //函数指针类型跟数组类型非常相似 / ...

  4. JSP数据库连接成功

    <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding= ...

  5. 【vijos】1763 Wormhole(贪心)

    https://vijos.org/p/1764 首先第一个虫洞一定是建在1号点. 证明如下: 假设一个虫洞在a,一个在b,a<b,那么走到k点的最短距离为 min{|x1-xk|, |x1-x ...

  6. js常用API汇总(转)

    typeof(); 检测数据类型 String(); 转换成字符串 parseInt(); 解析出一个string或number的整数部分 parseFloat(); 解析出一个string的浮点数部 ...

  7. js 风格(注意事项)

    类型   • 原始类型:我们可以直接使用值. ο string ο number ο boolean ο null ο undefined var foo = 1, bar = foo; bar = ...

  8. Django(模板语言-自定义filter和simple_tag)

    Django(模板语言-自定义filter和simple_tag)   filter过滤器的主要形式:变量|函数,意思是将变量交给函数处理,而自定义filter就是自己定义函数,因为用到已有的很少. ...

  9. IOS开发之 -- 线程初识

    对于开发者来说,多线程永远有这一层神秘的色彩,似乎是一到迈步过去的坎,在同步.异步.串行.并行.死锁这几个名字当中,逐渐的放弃治疗,下面就多线程,谈一下自己的认识,理解的肯定不全面,只是一些简单的皮毛 ...

  10. boost::interprocess::managed_shared_memory(2)(std::deque)

    struct shareDataEx : shareData { int index; int total_size; }; typedef managed_shared_memory::segmen ...