Food (hdu 4292 网络流sap模板题)

来源:互联网 发布:10月经济数据分析 编辑:程序博客网 时间:2024/05/17 23:13

Food

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3102    Accepted Submission(s): 1034


Problem Description
  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 31 1 11 1 1YYNNYYYNYYNYYNYYYNYYNNNY
 

Sample Output
3
 

Source
2012 ACM/ICPC Asia Regional Chengdu Online
 

Recommend
liuyiding   |   We have carefully selected several similar problems for you:  4288 4296 4295 4294 4293 

题意:有N个人,准备了F种食物和D种饮料,每个人都有喜欢的食物和饮料,这些食物和饮料最多能满足多少人。

思路:网络流,添加超级源点和食物相连,边权为该食物的数量,添加超级汇点和饮料相连,边权为该种饮料的数量,将人拆点,边权为1,建图,s->食物->人->人->饮料->e。dinic超时,用sap。

代码:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <string>#include <map>#include <stack>#include <vector>#include <set>#include <queue>#pragma comment (linker,"/STACK:102400000,102400000")#define maxn 1005#define MAXN 1005#define mod 1000000009#define INF 0x3f3f3f3f#define pi acos(-1.0)#define eps 1e-6#define lson rt<<1,l,mid#define rson rt<<1|1,mid+1,r#define FRE(i,a,b)  for(i = a; i <= b; i++)#define FRL(i,a,b)  for(i = a; i < b; i++)#define mem(t, v)   memset ((t) , v, sizeof(t))#define sf(n)       scanf("%d", &n)#define sff(a,b)    scanf("%d %d", &a, &b)#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)#define pf          printf#define DBG         pf("Hi\n")const int MAXM = 200010;typedef long long ll;using namespace std;struct Edge{    int to,next,cap,flow;}edge[MAXM];char str[222];int D,N,F;int tol;int head[MAXN];int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN];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 i,j,x;    while (~sfff(N,F,D))    {        init();        int s=0,e=F+D+2*N+1;        FRE(i,1,F)        {            sf(x);            addedge(s,i,x);        }        FRE(i,1,D)        {            sf(x);            addedge(F+2*N+i,e,x);        }        FRE(i,1,N)        {            scanf("%s",str);            int len=strlen(str);            FRL(j,0,len)            {                if (str[j]=='Y')                    addedge(j+1,F+i,1);            }        }        FRE(i,1,N)        {            scanf("%s",str);            int len=strlen(str);            FRL(j,0,len)            {                if (str[j]=='Y')                    addedge(F+N+i,F+2*N+j+1,1);            }        }        FRE(i,1,N)            addedge(F+i,F+N+i,1);        int ans=sap(s,e,e+1);        printf("%d\n",ans);    }    return 0;}



2 0
原创粉丝点击