hdu 4292 Food 最大流

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4292

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.

题意描述:你准备了F种食物(F<=200)和D种饮料(D<=200),每种食物和饮料都有一定的数量。有n个人(n<=200),每个人都有喜欢的食物和饮料并且只能吃自己喜欢的食物、喝喜欢的饮料,求出能够吃到喜欢的食物并喝到喜欢的饮料的最大人数。

算法分析:运用网络最大流求解即可。新增源点from和汇点to,from->食物(w为食物数量),饮料->to(w为饮料数量),对每个人 i 拆边 i 和 i+n ,喜欢的食物->i(w为1),i -> i+n(w为1),i+n->喜欢的饮料(w为1)。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<cmath>
  6 #include<algorithm>
  7 #include<vector>
  8 #include<queue>
  9 #define inf 0x7fffffff
 10 using namespace std;
 11 const int maxn=200+10;
 12 const int M = 999999;
 13 
 14 int n,F,D;
 15 int from,to,d[maxn*10];
 16 struct node
 17 {
 18     int v,flow;
 19     int next;
 20 }edge[M*2];
 21 int head[maxn*10],edgenum;
 22 
 23 void add(int u,int v,int flow)
 24 {
 25     edge[edgenum].v=v ;edge[edgenum].flow=flow;
 26     edge[edgenum].next=head[u];
 27     head[u]=edgenum++;
 28 
 29     edge[edgenum].v=u ;edge[edgenum].flow=0;
 30     edge[edgenum].next=head[v];
 31     head[v]=edgenum++;
 32 }
 33 
 34 int bfs()
 35 {
 36     memset(d,0,sizeof(d));
 37     d[from]=1;
 38     queue<int> Q;
 39     Q.push(from);
 40     while (!Q.empty())
 41     {
 42         int u=Q.front() ;Q.pop() ;
 43         for (int i=head[u] ;i!=-1 ;i=edge[i].next)
 44         {
 45             int v=edge[i].v;
 46             if (!d[v] && edge[i].flow>0)
 47             {
 48                 d[v]=d[u]+1;
 49                 Q.push(v);
 50                 if (v==to) return 1;
 51             }
 52         }
 53     }
 54     return 0;
 55 }
 56 
 57 int dfs(int u,int flow)
 58 {
 59     if (u==to || flow==0) return flow;
 60     int cap=flow;
 61     for (int i=head[u] ;i!=-1 ;i=edge[i].next)
 62     {
 63         int v=edge[i].v;
 64         if (d[v]==d[u]+1 && edge[i].flow>0)
 65         {
 66             int x=dfs(v,min(cap,edge[i].flow));
 67             cap -= x;
 68             edge[i].flow -= x;
 69             edge[i^1].flow += x;
 70             if (cap==0) return flow;
 71         }
 72     }
 73     return flow-cap;
 74 }
 75 
 76 int dinic()
 77 {
 78     int sum=0;
 79     while (bfs()) sum += dfs(from,inf);
 80     return sum;
 81 }
 82 
 83 int main()
 84 {
 85     while (scanf("%d%d%d",&n,&F,&D)!=EOF)
 86     {
 87         memset(head,-1,sizeof(head));
 88         edgenum=0;
 89         from=F+2*n+D+1;
 90         to=from+1;
 91         int a;
 92         for (int i=1 ;i<=F ;i++)
 93         {
 94             scanf("%d",&a);
 95             add(from,i,a);
 96         }
 97         for (int i=1 ;i<=D ;i++)
 98         {
 99             scanf("%d",&a);
100             add(F+2*n+i,to,a);
101         }
102         char str[maxn];
103         memset(str,0,sizeof(str));
104         for (int i=1 ;i<=n ;i++)
105         {
106             scanf("%s",str+1);
107             for (int j=1 ;j<=F ;j++)
108             {
109                 if (str[j]=='Y')
110                     add(j,F+i,1);
111             }
112         }
113         for (int i=1 ;i<=n ;i++)
114         {
115             scanf("%s",str+1);
116             for (int j=1 ;j<=D ;j++)
117             {
118                 if (str[j]=='Y')
119                     add(F+n+i,F+2*n+j,1);
120             }
121         }
122         for (int i=1 ;i<=n ;i++)
123             add(F+i,F+n+i,1);
124         printf("%d\n",dinic());
125     }
126     return 0;
127 }

 

 

 

posted @ 2015-03-09 22:03  huangxf  阅读(242)  评论(0编辑  收藏  举报