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.
题意:有若干人,他们各自有喜欢的食物和饮料,只有当获得一种他们喜欢的食物和一种他们喜欢的饮料,才算获得了服务。饮料和食物都有总数,所以只能服务一部分人。问最多能服务多少人。
分开建边,先超级源点和食物建边,流量是食物的数量。再是食物到人,流量1,再人到饮料,流量1,再饮料到超级汇点,流量是饮料的数量,这样就可以由人节点来控制一条增广路流量一定是1,即满足一个人的需求。
1 #include<stdio.h>
2 #include<string.h>
3 #include<vector>
4 #include<queue>
5 #include<algorithm>
6 using namespace std;
7 const int maxm=1000;
8 const int INF=0x3f3f3f3f;
9
10 struct edge{
11 int from,to,f;
12 edge(int a,int b,int c):from(a),to(b),f(c){}
13 };
14
15 struct dinic{
16 int s,t,m;
17 vector<edge>e;
18 vector<int>g[maxm];
19 bool vis[maxm];
20 int cur[maxm],d[maxm];
21
22 void init(int n){
23 for(int i=1;i<=n;i++)g[i].clear();
24 e.clear();
25 }
26
27 void add(int a,int b,int c){
28 e.push_back(edge(a,b,c));
29 e.push_back(edge(b,a,0));
30 m=e.size();
31 g[a].push_back(m-2);
32 g[b].push_back(m-1);
33 }
34
35 bool bfs(){
36 memset(vis,0,sizeof(vis));
37 queue<int>q;
38 q.push(s);
39 vis[s]=1;
40 d[s]=0;
41 while(!q.empty()){
42 int u=q.front();
43 q.pop();
44 for(int i=0;i<g[u].size();i++){
45 edge tmp=e[g[u][i]];
46 if(!vis[tmp.to]&&tmp.f>0){
47 d[tmp.to]=d[u]+1;
48 vis[tmp.to]=1;
49 q.push(tmp.to);
50 }
51 }
52 }
53 return vis[t];
54 }
55
56 int dfs(int x,int a){
57 if(x==t||a==0)return a;
58 int flow=0,f;
59 for(int& i=cur[x];i<g[x].size();i++){
60 edge& tmp=e[g[x][i]];
61 if(d[tmp.to]==d[x]+1&&tmp.f>0){
62 f=dfs(tmp.to,min(a,tmp.f));
63 tmp.f-=f;
64 e[g[x][i]^1].f+=f;
65 flow+=f;
66 a-=f;
67 if(a==0)break;
68 }
69 }
70 if(flow==0)d[x]=-1;
71 return flow;
72 }
73
74 int mf(int s,int t){
75 this->s=s;
76 this->t=t;
77 int flow=0;
78 while(bfs()){
79 memset(cur,0,sizeof(cur));
80 flow+=dfs(s,INF);
81 }
82 return flow;
83 }
84 };
85
86 char ss[250];
87
88 int main(){
89 int n,f,d;
90 while(scanf("%d%d%d",&n,&f,&d)!=EOF){
91 int i,j;
92 dinic D;
93 D.init(f+2*n+d+5);
94 for(i=f+1;i<=f+n;i++){
95 D.add(i,i+n,1);
96 }
97 for(i=1;i<=f;i++){
98 int a;
99 scanf("%d",&a);
100 D.add(0,i,a);
101 }
102 for(i=1;i<=d;i++){
103 int a;
104 scanf("%d",&a);
105 D.add(f+2*n+i,f+2*n+d+1,a);
106 }
107 for(i=1;i<=n;i++){
108 scanf("%s",ss+1);
109 for(j=1;j<=f;j++){
110 if(ss[j]=='Y')D.add(j,f+i,1);
111 }
112 }
113 for(i=1;i<=n;i++){
114 scanf("%s",ss+1);
115 for(j=1;j<=d;j++){
116 if(ss[j]=='Y')D.add(f+n+i,f+2*n+j,1);
117 }
118 }
119 printf("%d
",D.mf(0,f+2*n+d+1));
120 }
121 return 0;
122 }