[luogu1402]酒店之王
将每个人拆成两个节点,一端连房间,一端连食物,然后跑最大流。
(同某道牛-食物-饮料)
(没写cur优化。。。)

1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstring> 5 #include <cstdlib> 6 #include <queue> 7 #include <string> 8 #include <vector> 9 #include <cmath> 10 #include <map> 11 using namespace std; 12 13 const int N=20000; 14 int n,p,q,S,T; 15 int h[N],r[N],to[N],flow[N],tot; 16 void add(int u,int v,int f){ 17 to[tot]=v; 18 flow[tot]=f; 19 r[tot]=h[u]; 20 h[u]=tot++; 21 } 22 void ins(int u,int v,int f){ 23 add(u,v,f); 24 add(v,u,0); 25 } 26 int num; 27 map<int,int>man1,man2,room,food; 28 29 int Man1(int i){ 30 if(man1[i]==0)man1[i]=++num; 31 return man1[i]; 32 } 33 int Man2(int i){ 34 if(man2[i]==0)man2[i]=++num; 35 return man2[i]; 36 } 37 int Room(int i){ 38 if(room[i]==0)room[i]=++num; 39 return room[i]; 40 } 41 int Food(int i){ 42 if(food[i]==0)food[i]=++num; 43 return food[i]; 44 } 45 46 int d[N],vv[N],cur[N]; 47 int bfs(){ 48 memset(vv,0,sizeof(vv)); 49 memset(d,0,sizeof(d)); 50 queue<int>q; 51 q.push(S); 52 d[S]=1; 53 vv[S]=1; 54 while(q.size()){ 55 int u=q.front();q.pop(); 56 for(int i=h[u];i!=-1;i=r[i]){ 57 int v=to[i]; 58 if(flow[i]&&!vv[v]){ 59 d[v]=d[u]+1; 60 q.push(v); 61 vv[v]=1; 62 } 63 } 64 } 65 return d[T]; 66 } 67 int dfs(int x,int f){ 68 if(x==T||!f)return f; 69 int ret=0; 70 for(int i=h[x];i!=-1;i=r[i]){ 71 int y=to[i],ff; 72 if(d[y]==d[x]+1&&(ff=dfs(y,min(f,flow[i])))>0){ 73 f-=ff; 74 flow[i]-=ff; 75 flow[i^1]+=ff; 76 ret+=ff; 77 if(!f)break; 78 } 79 } 80 return ret; 81 } 82 83 int mf(){ 84 int f=0; 85 while(bfs())f+=dfs(S,0x3f3f3f3f); 86 return f; 87 } 88 89 int main(){ 90 memset(h,-1,sizeof(h)); 91 scanf("%d%d%d",&n,&p,&q); 92 for(int i=1;i<=n;i++){ 93 for(int j=1,t;j<=p;j++){ 94 scanf("%d",&t); 95 if(t)ins(Room(j),Man1(i),1); 96 } 97 } 98 for(int i=1;i<=n;i++){ 99 for(int j=1,t;j<=q;j++){ 100 scanf("%d",&t); 101 if(t)ins(Man2(i),Food(j),1); 102 } 103 } 104 for(int i=1;i<=p;i++)ins(S,Room(i),1); 105 for(int i=1;i<=n;i++)ins(Man1(i),Man2(i),1); 106 for(int i=1;i<=q;i++)Food(i); 107 T=++num; 108 for(int i=1;i<=q;i++)ins(Food(i),T,1); 109 printf("%d\n",mf()); 110 }