「LuoguP1402」 酒店之王(最大流
Posted qwerta
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「LuoguP1402」 酒店之王(最大流相关的知识,希望对你有一定的参考价值。
题目描述
XX酒店的老板想成为酒店之王,本着这种希望,第一步要将酒店变得人性化。由于很多来住店的旅客有自己喜好的房间色调、阳光等,也有自己所爱的菜,但是该酒店只有p间房间,一天只有固定的q道不同的菜。
有一天来了n个客人,每个客人说出了自己喜欢哪些房间,喜欢哪道菜。但是很不幸,可能做不到让所有顾客满意(满意的条件是住进喜欢的房间,吃到喜欢的菜)。
这里要怎么分配,能使最多顾客满意呢?
输入输出格式
输入格式:第一行给出三个正整数表示n,p,q(<=100)。
之后n行,每行p个数包含0或1,第i个数表示喜不喜欢第i个房间(1表示喜欢,0表示不喜欢)。
之后n行,每行q个数,表示喜不喜欢第i道菜。
输出格式:最大的顾客满意数。
输入输出样例
题解
这是道三倍经验题。
对人拆点,设为$x_1,x_2$。
从$S$往每个房间连边,容量为$1$。
从每个房间往喜欢它的$x_1$连边,容量为$1$。
从每个$x_1$往对应的$x_2$连边,容量为$1$。(限流
从每个$x_2$往他喜欢的菜连边,容量为$1$。
最后从每道菜往$T$连$1$,跑最大流就是答案了。
1 /* 2 qwerta 3 P1402 酒店之王 4 Accepted 5 100 6 代码 C++,1.69KB 7 提交时间 2018-10-13 10:38:07 8 耗时/内存 9 34ms, 796KB 10 */ 11 #include<iostream> 12 #include<cstring> 13 #include<cstdio> 14 #include<queue> 15 using namespace std; 16 struct emm{ 17 int e,f,v; 18 }a[50003]; 19 int h[413]; 20 int tot=1; 21 void con(int x,int y,int ds) 22 { 23 a[++tot].f=h[x]; 24 h[x]=tot; 25 a[tot].e=y; 26 a[tot].v=ds; 27 a[++tot].f=h[y]; 28 h[y]=tot; 29 a[tot].e=x; 30 return; 31 } 32 queue<int>que; 33 int d[413]; 34 int s,t; 35 inline bool bfs() 36 { 37 memset(d,0,sizeof(d)); 38 d[s]=1;que.push(s); 39 while(!que.empty()) 40 { 41 int x=que.front();que.pop(); 42 for(int i=h[x];i;i=a[i].f) 43 if(!d[a[i].e]&&a[i].v) 44 { 45 d[a[i].e]=d[x]+1; 46 que.push(a[i].e); 47 } 48 } 49 return d[t]; 50 } 51 int dfs(int x,int al) 52 { 53 if(x==t||!al)return al; 54 int fl=0; 55 for(int i=h[x];i;i=a[i].f) 56 if(d[a[i].e]==d[x]+1&&a[i].v) 57 { 58 int f=dfs(a[i].e,min(al,a[i].v)); 59 if(f) 60 { 61 fl+=f; 62 al-=f; 63 a[i].v-=f; 64 a[i^1].v+=f; 65 if(!al)break; 66 } 67 } 68 if(!fl)d[x]=-1; 69 return fl; 70 } 71 int main() 72 { 73 //freopen("a.in","r",stdin); 74 int n,p,q; 75 scanf("%d%d%d",&n,&p,&q); 76 s=0,t=2*n+p+q+1; 77 for(int i=1;i<=p;++i) 78 con(s,i,1); 79 for(int i=1;i<=n;++i) 80 { 81 for(int j=1;j<=p;++j) 82 { 83 int x; 84 scanf("%d",&x); 85 if(x) 86 con(j,i+p,1); 87 } 88 } 89 for(int i=1;i<=n;++i) 90 con(i+p,i+p+n,1); 91 for(int i=1;i<=n;++i) 92 { 93 for(int j=1;j<=q;++j) 94 { 95 int x; 96 scanf("%d",&x); 97 if(x) 98 con(i+p+n,j+p+n+n,1); 99 } 100 } 101 for(int i=1;i<=q;++i) 102 con(i+p+n+n,t,1); 103 int ans=0; 104 while(bfs())ans+=dfs(s,99999999); 105 cout<<ans; 106 return 0; 107 }
以上是关于「LuoguP1402」 酒店之王(最大流的主要内容,如果未能解决你的问题,请参考以下文章
P1402 酒店之王
P2891 [USACO07OPEN]吃饭Dining
P1231 教辅的组成
三题读入不一样,P1231数据范围稍大一点,就这点区别。。