题面:
思路:
又是一道网络流水题......
这道题一眼看来不难,就是一个食物和水的二分图
但是问题来了
怎么做到每个人只拿一份食物一份水呢?
显然每个人分配一个点是不够的
那我们就要使用拆点的技巧,把一个人拆成两个点,中间连一条容量为1的边,这两个点再分别和食物、水相连
食物和源点连,水连到汇点,然后源汇最大流就是答案了、
Code:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define inf 1e9 6 using namespace std; 7 inline int read(){ 8 int re=0,flag=1;char ch=getchar(); 9 while(ch>'9'||ch<'0'){ 10 if(ch=='-') flag=-1; 11 ch=getchar(); 12 } 13 while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar(); 14 return re*flag; 15 } 16 int n,F,D,cnt,ans,first[1010],dep[1010],cur[1010]; 17 struct edge{ 18 int to,next,w; 19 }a[300010]; 20 inline void add(int u,int v,int w){ 21 // cout<<"add "<<u<<ends<<v<<ends<<w<<endl; 22 a[++cnt]=(edge){v,first[u],w};first[u]=cnt; 23 a[++cnt]=(edge){u,first[v],0};first[v]=cnt; 24 } 25 void init(){ 26 memset(first,-1,sizeof(first));memset(a,0,sizeof(a)); 27 cnt=-1,ans=0; 28 } 29 bool bfs(int s,int t){ 30 int q[1010],head=0,tail=1,i,u,v; 31 for(i=s;i<=t;i++) dep[i]=-1,cur[i]=first[i]; 32 dep[s]=0;q[0]=s; 33 while(head<tail){ 34 u=q[head++]; 35 for(i=first[u];~i;i=a[i].next){ 36 v=a[i].to; 37 if(~dep[v]||!a[i].w) continue; 38 dep[v]=dep[u]+1;q[tail++]=v; 39 } 40 } 41 return ~dep[t]; 42 } 43 int dfs(int u,int t,int limit){ 44 if(u==t||!limit) return limit; 45 int i,v,f,flow=0; 46 for(i=cur[u];~i;i=a[i].next){ 47 cur[u]=i;v=a[i].to; 48 if(dep[v]==dep[u]+1&&(f=dfs(v,t,min(limit,a[i].w)))){ 49 flow+=f;limit-=f; 50 a[i].w-=f;a[i^1].w+=f; 51 if(!limit) return flow; 52 } 53 } 54 return flow; 55 } 56 void dinic(int s,int t){ 57 while(bfs(s,t)) ans+=dfs(s,t,inf); 58 } 59 int main(){ 60 int i,j,t1;char s[210]; 61 while(~scanf("%d%d%d",&n,&F,&D)){ 62 init(); 63 for(i=1;i<=n;i++) add(F+i,F+n+i,1); 64 for(i=1;i<=F;i++) t1=read(),add(0,i,t1); 65 for(i=1;i<=D;i++) t1=read(),add(F+n*2+i,F+D+n*2+1,t1); 66 for(i=1;i<=n;i++){ 67 scanf("%s",s); 68 for(j=1;j<=F;j++){ 69 if(s[j-1]=='Y') add(j,F+i,inf); 70 } 71 } 72 for(i=1;i<=n;i++){ 73 scanf("%s",s); 74 for(j=1;j<=D;j++){ 75 if(s[j-1]=='Y') add(F+n+i,F+n*2+j,inf); 76 } 77 } 78 dinic(0,F+D+n*2+1); 79 printf("%d ",ans); 80 } 81 }