Food(拆点建图,网络流)
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.
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).
#include <bits/stdc++.h>
#define maxn 10005
using namespace std;
struct Person
{
string food,drink;
}person[maxn];
const int inf= 1e9;
struct Edge
{
int u,v,c,flow;
Edge(int a,int b,int cc,int f):u(a),v(b),c(cc),flow(f){}
};
struct Dinic
{
int s,t;
vector<Edge> edges;
vector<int> pre[maxn];
bool vis[maxn];
int dist[maxn];
int cur[maxn];
void init()
{
for(int i=0;i<maxn;i++)
{
pre[i].clear();
}
edges.clear();
}
void Addedge(int u,int v,int f)
{
edges.push_back(Edge(u,v,f,0));
edges.push_back(Edge(v,u,0,0));
int mm=edges.size();
pre[u].push_back(mm-2);
pre[v].push_back(mm-1);
}
bool bfs()
{
memset(vis,false,sizeof(vis));
queue<int> q;
q.push(s);
vis[s]=1;
dist[s]=0;
while(!q.empty())
{
int now=q.front();
q.pop();
for(int i=0;i<pre[now].size();i++)
{
Edge &e=edges[pre[now][i]];
if(!vis[e.v]&&e.c>e.flow)
{
dist[e.v]=dist[now]+1;
vis[e.v]=true;
q.push(e.v);
}
}
}
return vis[t];
}
int dfs(int x,int cap)
{
if(x==t||cap==0) return cap;
int f,flow=0;
for(int &i=cur[x];i<pre[x].size();i++)
{
cur[x]=i;
Edge &e=edges[pre[x][i]];
if(dist[e.v]==dist[x]+1&&(f=dfs(e.v,min(cap,e.c-e.flow))))
{
e.flow+=f;
edges[pre[x][i]^1].flow-=f;
flow+=f;
cap-=f;
if(cap==0) break;
}
}
return flow;
}
int Maxflow(int s,int t)
{
this->s=s;
this->t=t;
int flow=0;
while(bfs())
{
memset(cur,0,sizeof(cur));
flow+=dfs(s,inf);
}
return flow;
}
}dc;
int main()
{
int n,f,d,i;
while(cin>>n>>f>>d)
{
dc.init();
int a[maxn]={0};
int b[maxn]={0};
for(i=1;i<=f;i++)
{
scanf("%d",&a[i]);
}
for(i=1;i<=d;i++)
{
scanf("%d",&b[i]);
}
for(i=1;i<=n;i++)
{
cin>>person[i].food;
}
for(i=1;i<=n;i++)
{
cin>>person[i].drink;
}
for(i=1;i<=n;i++)
{
for(int j=0;j<f;j++)
{
if(person[i].food[j]=='Y')
{
dc.Addedge(j+1,f+i,1);
}
}
}
for(i=1;i<=n;i++)
{
dc.Addedge(f+i,f+n+i,1);
}
for(i=1;i<=n;i++)
{
for(int j=0;j<d;j++)
{
if(person[i].drink[j]=='Y')
{
dc.Addedge(f+n+i,f+2*n+j+1,1);
}
}
}
for(i=1;i<=f;i++)
{
dc.Addedge(0,i,a[i]);
}
for(i=1;i<=d;i++)
{
dc.Addedge(f+2*n+i,f+2*n+d+1,b[i]);
}
printf("%d\n",dc.Maxflow(0,f+2*n+d+1));
}
return 0;
}

浙公网安备 33010602011771号