[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 }
View Code

 

posted @ 2017-01-28 22:10  KingSann  阅读(140)  评论(0编辑  收藏  举报