1. 程式人生 > >「LuoguP1402」 酒店之王(最大流

「LuoguP1402」 酒店之王(最大流

comm accepted gin strong 輸入輸出 eof spa namespace ++

題目描述

XX酒店的老板想成為酒店之王,本著這種希望,第一步要將酒店變得人性化。由於很多來住店的旅客有自己喜好的房間色調、陽光等,也有自己所愛的菜,但是該酒店只有p間房間,一天只有固定的q道不同的菜。

有一天來了n個客人,每個客人說出了自己喜歡哪些房間,喜歡哪道菜。但是很不幸,可能做不到讓所有顧客滿意(滿意的條件是住進喜歡的房間,吃到喜歡的菜)。

這裏要怎麽分配,能使最多顧客滿意呢?

輸入輸出格式

輸入格式:

第一行給出三個正整數表示n,p,q(<=100)。

之後n行,每行p個數包含0或1,第i個數表示喜不喜歡第i個房間(1表示喜歡,0表示不喜歡)。

之後n行,每行q個數,表示喜不喜歡第i道菜。

輸出格式:

最大的顧客滿意數。

輸入輸出樣例

輸入樣例#1: 復制
2 2 2
1 0
1 0
1 1
1 1
輸出樣例#1: 復制
1

題解

這是道三倍經驗題。

@hongzy 2018-10-05 22:14 回復

P1402 酒店之王

P2891 [USACO07OPEN]吃飯Dining

P1231 教輔的組成

三題讀入不一樣,P1231數據範圍稍大一點,就這點區別。。

對人拆點,設為$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」 酒店之王(最大流