//网络流,直接对人进行拆点,边权值为1,构成的网络流就是:源点->food->人->人->drink->汇点的一个五层结构
//直接写了个裸的,代码如下:
#include<stdio.h> #include<queue> #include<string.h> using namespace std; #define inf 100000000 int map[1000][1000]; struct edge { int to,next; }edge[200000]; int YY[220],XX[220],vis[1100],pre[1100],end; int ant,head[1100]; void add(int a,int b) { edge[ant].to=b; edge[ant].next=head[a]; head[a]=ant++; } void dfs(int root) { int i,to; vis[root]=1; if(vis[end])return; for(i=head[root];i!=-1;i=edge[i].next) { to=edge[i].to; if(vis[to]||map[root][to]==0)continue; pre[to]=root; dfs(to); } } int dinic(int start) { int sum=0; while(1) { memset(vis,0,sizeof(vis)); dfs(start); if(!vis[end])break; int Min=inf,u=end; while(1) { if(u==start)break; if(map[pre[u]][u]<Min) Min=map[pre[u]][u]; u=pre[u]; } sum+=Min; u=end; while(1) { if(u==start)break; map[pre[u]][u]-=Min; map[u][pre[u]]+=Min; add(u,pre[u]); u=pre[u]; } } return sum; } int main() { char op[220]; int n,m1,m2,i,j; while(scanf("%d%d%d",&n,&m1,&m2)!=EOF) { ant=0; memset(head,-1,sizeof(head)); end=2+m1+2*n+m2; for(i=1;i<=end;i++) { for(j=1;j<=end;j++) map[i][j]=0; } for(i=1;i<=m1;i++) scanf("%d",&XX[i]); for(i=1;i<=m2;i++) scanf("%d",&YY[i]); for(i=2,j=1;i<=m1+1;i++,j++) { map[1][i]=XX[j]; add(1,i); } for(i=1+m1+1;i<=1+m1+n;i++) { map[i][i+n]=1; add(i,i+n); } for(i=1+m1+2*n+1,j=1;i<end;i++,j++) { add(i,end); map[i][end]=YY[j]; } for(i=1;i<=n;i++) { scanf("%s",op); for(j=1;op[j-1];j++) { if(op[j-1]=='Y') { map[1+j][m1+1+i]=1; add(1+j,m1+1+i); } } } for(i=1;i<=n;i++) { scanf("%s",op); for(j=1;op[j-1];j++) { if(op[j-1]=='Y') { map[1+m1+n+i][1+m1+2*n+j]=1; add(1+m1+n+i,1+m1+2*n+j); } } } printf("%d\n",dinic(1)); } return 0; }