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.
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.
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).
4 3 3 1 1 1 1 1 1 YYN NYY YNY YNY YNY YYN YYN NNY
3
题意:与牛Dining类似,N个人,F中食物,D中饮料;第二行有F个数,表示每种食物的个数,第三行有D个数,表示每种饮料的个数;接下来4~N+4行,每行有F个字符,表示对每种食物的爱好,N+5~最后,表示对每种饮料的爱好;
对人拆点,容量为1,汇点指向食物,容量为食物的个数,饮料指向汇点,容量为饮料的个数;Dinic模板
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
#include<string>
using namespace std;
const int MAXN=1000+10;
const int inf=0x3f3f3f3f3f;
int n,F,D,N;
int edn;//边数
int dis[MAXN],head[MAXN];
struct node
{
int v,w;
int next;
}Edge[MAXN*MAXN];
void AddEdge(int u,int v,int w)//邻接表存图
{
Edge[edn].v=v,Edge[edn].w=w;
Edge[edn].next=head[u],head[u]=edn++;
Edge[edn].v=u,Edge[edn].w=0;
Edge[edn].next=head[v],head[v]=edn++;
}
int bfs()
{
queue<int>s;
memset(dis,-1,sizeof(dis));
dis[0]=0;
s.push(0);
while(!s.empty())
{
int now=s.front();
s.pop();
for(int i=head[now];i!=-1;i=Edge[i].next)
{
int u=Edge[i].v;
if(dis[u]==-1&&Edge[i].w>0)//只考虑网络中有残量的弧
{
dis[u]=dis[now]+1;
s.push(u);
}
}
}
return dis[N+1]!=-1;
}
int dfs(int a,int b)
{
if(a==N+1) return b;
int flow;
for(int i=head[a];i!=-1;i=Edge[i].next)
{
int u=Edge[i].v;
if(dis[a]+1==dis[u]&&Edge[i].w>0&&(flow=dfs(u,min(b,Edge[i].w)))>0)
{
Edge[i].w-=flow;
Edge[i^1].w+=flow;
return flow;
}
}
dis[a]=-1;
return 0;
}
int Dinic()
{
int flow=0,temp;
while(bfs())
{
while(temp=dfs(0,inf))
flow+=temp;
}
return flow;
}
int main()
{
while(~scanf("%d%d%d",&n,&F,&D))
{
N=2*n+F+D;
memset(head,-1,sizeof(head));
edn=0;
int a;
for(int i=1;i<=F;i++)
{
scanf("%d",&a);
AddEdge(0,2*n+i,a);
}
for(int i=1;i<=D;i++)
{
scanf("%d",&a);
AddEdge(2*n+F+i,N+1,a);
}
char s[MAXN];
for(int i=1;i<=n;i++)
{
scanf("%s",s);
for(int j=1;j<=F;j++)
{
if(s[j-1]=='Y')
{
AddEdge(2*n+j,i,1);
}
}
AddEdge(i,n+i,1);
}
for(int i=1;i<=n;i++)
{
scanf("%s",s);
for(int j=1;j<=D;j++)
{
if(s[j-1]=='Y')
{
AddEdge(n+i,2*n+F+j,1);
}
}
}
printf("%d\n",Dinic());
}
}