hdu4292Food (最大流拆点)

 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. 
Input  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). 
Output  For each test case, please print a single line with one integer, the maximum number of people to be satisfied. 
Sample Input
4 3 3
1 1 1
1 1 1
YYN
NYY
YNY
YNY
YNY
YYN
YYN
NNY
Sample Output
3

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
const int inf = 0x3f3f3f3f;
const int mod=609929123;
const int N=1220;
int n,f,d;
int S,T,R;
struct node
{
    int u,v,cap,next;
}es[400*N];
int frist[N];
int dis[N];
int current[N];
void init()
{
    memset(frist,-1,sizeof(frist));
    R=0;
    S=0;
    T=f+2*n+d+1;
}
int addedge(int u,int v,int cap)
{
    node  e1={u,v,cap,frist[u]};
    es[R]=e1;
    frist[u]=R++;
    node e2={v,u,0,frist[v]};
    es[R]=e2;
    frist[v]=R++;
}
void getmap()
{
    int a;
    for(int i=1;i<=n;i++)
      addedge(f+i,f+n+i,1);
    for(int i=1;i<=f;i++)
    {
        scanf("%d",&a);
        addedge(S,i,a);
    }
    for(int i=1;i<=d;i++)
    {
        scanf("%d",&a);
        addedge(i+2*n+f,T,a);
    }
    char s[300];
    for(int i=1;i<=n;i++)
    {
        scanf("%s",s);
        for(int j=0;j<f;j++)
        {
            if(s[j]=='Y')
                addedge(j+1,f+i,1);
        }
    }
    for(int i=1;i<=n;i++)
    {
        scanf("%s",s);
        for(int j=0;j<d;j++)
        {
            if(s[j]=='Y')
                addedge(f+n+i,f+2*n+j+1,1);
        }
    }
}
int bfs()
{
  queue<int>q;
  q.push(S);
  memset(dis,-1,sizeof(dis));
  dis[S]=0;
  while(!q.empty())
  {
      int h=q.front();
      q.pop();
      if(h==T)
        return 1;
      for(int i=frist[h];i!=-1;i=es[i].next)
      {
          int temp=es[i].v;
          if(dis[temp]==-1&&es[i].cap)
          {
              dis[temp]=dis[h]+1;
              q.push(temp);
          }
      }
  }
  return 0;
}
int dinic(int x,int maxflow)
{
  if(x==T) return maxflow;
  int flow,f=0;
  for(int &i=current[x];i!=-1;i=es[i].next)
  {
      int temp=es[i].v;
      if(dis[temp]==dis[x]+1&&es[i].cap)
      {
      flow=dinic(temp,min(maxflow-f,es[i].cap));
      es[i].cap-=flow;
      es[i^1].cap+=flow;
      f+=flow;
      if(f==maxflow) break;
      }
  }
  return f;
}
int DINIC()
{
 int ans=0;
 while(bfs())
 {
     int flow;
     memcpy(current,&frist,sizeof(frist));
     while(flow=dinic(S,inf))
        ans+=flow;
 }
 return ans;
}
int main()
{
    while(~scanf("%d%d%d",&n,&f,&d))
    {
        init();
        getmap();
        printf("%d\n",DINIC());
    }
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值