HDU 4292 Food 网络流最大流 拆点
2016-05-13 09:21
666 查看
在使用网络流之前,最重要的一件事就是构造流量图,必须保证从源点到汇点的一条路径是一个可行解才行。
对于这道题目,由于每个人既要吃饭,还要喝饮料,因此就不能把一个人当成“一”个人看待,因为如果看成一个人,那么无论怎么建图,都无法保证从源到汇的路径是可行解,这时候我们就需要将一个人拆成两个,一个负责吃饭,一个负责喝饮料,然后再让吃饭的人指向喝饮料的人,容量为1。最后在建立食物与人的边喝人与饮料的边,说起来比较抽象,见下图。
Problem - 4292
查看原文:http://colorfulshark.cn/wordpress/food-1014.html
对于这道题目,由于每个人既要吃饭,还要喝饮料,因此就不能把一个人当成“一”个人看待,因为如果看成一个人,那么无论怎么建图,都无法保证从源到汇的路径是可行解,这时候我们就需要将一个人拆成两个,一个负责吃饭,一个负责喝饮料,然后再让吃饭的人指向喝饮料的人,容量为1。最后在建立食物与人的边喝人与饮料的边,说起来比较抽象,见下图。
Problem - 4292
FoodTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4534 Accepted Submission(s): 1533 [align=left]Problem Description[/align] You, a part-time dining service worker in your college’s dining hall, are now confused with a new problem: serve as many people as possible. The issue comes up as people in your college are more and more difficult to serve with meal: They eat only some certain kinds of food and drink, and with requirement unsatisfied, go away directly. You have prepared F (1 <= F <= 200) kinds of food and D (1 <= D <= 200) kinds of drink. Each kind of food or drink has certain amount, that is, how many people could this food or drink serve. Besides, You know there’re N (1 <= N <= 200) people and you too can tell people’s personal preference for food and drink. Back to your goal: to serve as many people as possible. So you must decide a plan where some people are served while requirements of the rest of them are unmet. You should notice that, when one’s requirement is unmet, he/she would just go away, refusing any service. [align=left]Input[/align] There are several test cases. For each test case, the first line contains three numbers: N,F,D, denoting the number of people, food, and drink. The second line contains F integers, the ith number of which denotes amount of representative food. The third line contains D integers, the ith number of which denotes amount of representative drink. Following is N line, each consisting of a string of length F. e jth character in the ith one of these lines denotes whether people i would accept food j. “Y” for yes and “N” for no. Following is N line, each consisting of a string of length D. e jth character in the ith one of these lines denotes whether people i would accept drink j. “Y” for yes and “N” for no. Please process until EOF (End Of File). [align=left]Output[/align] For each test case, please print a single line with one integer, the maximum number of people to be satisfied. [align=left]Sample Input[/align] 4 3 3 1 1 1 1 1 1 YYN NYY YNY YNY YNY YYN YYN NNY [align=left]Sample Output[/align] 3 [align=left]Source[/align] 2012 ACM/ICPC Asia Regional Chengdu Online |
#include <iostream> #include <stdio.h> #include <string.h> using namespace std; const int MAXN=10001; const int MAXM=4000100; const int INF=99999999; struct Edge { int to,next,cap,flow; }; Edge edge[MAXM]; int head[MAXN],tol; int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN]; int N,F,D; int num; void init() { tol=0; memset(head,-1,sizeof(head)); } void addedge(int u,int v,int w,int rw=0) { edge[tol].to=v; edge[tol].cap=w; edge[tol].next=head[u]; edge[tol].flow=0; head[u]=tol++; edge[tol].to=u; edge[tol].cap=rw; edge[tol].next=head[v]; edge[tol].flow=0; head[v]=tol++; } int sap(int start,int end,int N) { memset(gap,0,sizeof(gap)); memset(dep,0,sizeof(dep)); memcpy(cur,head,sizeof(head)); int u=start; pre[u]=-1; gap[0]=N; int ans=0; while(dep[start]<N) { if(u==end) { int Min=INF; for(int i=pre[u];i!=-1;i=pre[edge[i^1].to]) if(Min>edge[i].cap-edge[i].flow) Min=edge[i].cap-edge[i].flow; for(int i=pre[u];i!=-1;i=pre[edge[i^1].to]) { edge[i].flow+=Min; edge[i^1].flow-=Min; } u=start; ans+=Min; continue; } bool flag=false; int v; for(int i=cur[u];i!=-1;i=edge[i].next) { v=edge[i].to; if(edge[i].cap-edge[i].flow&&dep[v]+1==dep[u]) { flag=true; cur[u]=pre[v]=i; break; } } if(flag) { u=v; continue; } int Min=N; for(int i=head[u];i!=-1;i=edge[i].next) if(edge[i].cap-edge[i].flow&&dep[edge[i].to]<Min) { Min=dep[edge[i].to]; cur[u]=i; } gap[dep[u]]--; if(!gap[dep[u]]) return ans; dep[u]=Min+1; gap[dep[u]]++; if(u!=start) u=edge[pre[u]^1].to; } return ans; } int main() { int source,sink; int ans; string req; while(~scanf("%d%d%d",&N,&F,&D)) { source=0; sink=2*N+F+D+1; init(); for(int i=1;i<=F;i++) { scanf("%d",&num); addedge(source,i,num);//源点指向所有食物 } for(int i=F+2*N+1;i<=F+2*N+D;i++) { scanf("%d",&num); addedge(i,sink,num);//所有饮料指向汇点 } for(int i=F+1;i<=F+N;i++)//吃饭的人指向喝饮料的人 addedge(i,i+N,1); for(int i=1;i<=N;i++) { cin>>req; for(unsigned int j=0;j<req.size();j++) { if(req[j]=='Y') addedge(j+1,i+F,1);//饭指向人 } } for(int i=1;i<=N;i++) { cin>>req; for(unsigned int j=0;j<req.size();j++) { if(req[j]=='Y') addedge(F+N+i,j+2*N+F+1,1);//人指向饮料 //maze[N+i][j+2*N+F+1]=1; } } ans=sap(source,sink,sink+1); printf("%d\n",ans); } return 0; }
查看原文:http://colorfulshark.cn/wordpress/food-1014.html
相关文章推荐
- C#对HTTP数据还原
- SpringMVC @ResponseBody 415错误处理及org.springframework.http.converter.json.MappingJacksonHttpMessageCon
- XDroidRequest - 一款基于Android 6.0 网络请求框架
- https原理:证书传递、验证和数据加密、解密过程解析
- NIO框架(2)---Channel
- 一个超级好用的加载网络图片的轮播图(3行代码就可搞定)
- android之HttpURLConnection
- HTTP Service服务去哪啦?
- 1.2.2 网络抓包工具之:Charles
- 安卓中进行基于Http协议的网络访问基础总结-1
- Android开发本地及网络Mp3音乐播放器(十七)已存在歌曲歌词下载
- Android开发本地及网络Mp3音乐播放器(十七)已存在歌曲歌词下载
- 在 .NET 中远程请求 https 内容时,发生错误:根据验证过程,远程证书无效。
- PHP问题 —— failed to open stream: HTTP request faile
- 因缺乏品牌意识 宁夏某知名企业网络域名遭抢注
- 安卓使用OkHttpClient进行网络请求
- 几种TCP连接中出现RST的情况
- Swift中的HTTP请求
- php http请求
- oracle12c不能进入到http://localhost:5500/em的解决办法