[洛谷P1402] 酒店之王
生活随笔
收集整理的這篇文章主要介紹了
[洛谷P1402] 酒店之王
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
洛谷連接:酒店之王
題目描述
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
首先分析一下題意:給出n個人,p間房,q道菜,一個人只能要一間房,一道菜,如果一個人得到了他要的房間和菜,就可以使這個顧客滿意,要統計最大的顧客滿意數。
那么既然給出了限制條件,并且我們只需要知道最大的滿意數,并不需要知道方案如何。所以我們考慮用網絡流來做。那么我們肯定是要將人,房間和菜相連來跑最大流的。所以我們想要如何保證流通一個人和菜和房間后,只能增加1的流量。首先我們可以想到拆點。可以把人,菜和房間都拆成兩個點,這樣就能保證流過這個點的時候流量最大為1。
但是這樣很顯然是把問題復雜化了,因為只給出了人和房間,菜品的關系,所以我們可以考慮這樣建圖:
把人和房間,人和菜品相連。
將房間和源點相連,菜品和匯點相連。
將人拆成兩個點限制流量。
這樣就可以比較簡單解決問題(當然如果全部拆點應該也能過)。
1 #include<bits/stdc++.h>
2 using namespace std;
3 const int N=3000+5;
4 const int inf=2147483647;
5
6 int s, t;
7 int n, room, meal;
8 int cnt = 1;
9 int last[N];
10 int lev[N];
11 int ans = 0;
12
13 struct edge{
14 int to, next, cap;
15 }e[1000005];
16
17 void add(int x,int y,int z){
18 e[++cnt].to = y;
19 e[cnt].cap = z;
20 e[cnt].next = last[x];
21 last[x] = cnt;
22 }
23
24 bool bfs(){
25 queue <int> q;
26 memset(lev,-1,sizeof(lev));
27 lev[s] = 0 , q.push(s);
28 while(!q.empty()){
29 int x = q.front(); q.pop();
30 for(int i=last[x];i;i=e[i].next){
31 int to = e[i].to;
32 if(lev[to] == -1 && e[i].cap)
33 lev[to] = lev[x]+1 , q.push(to);
34 }
35 }
36 return lev[t] != -1;
37 }
38
39 int dfs(int x,int flow){
40 int rest = 0;
41 if(x == t) return flow;
42 for(int i=last[x];i;i=e[i].next){
43 int to = e[i].to;
44 if(lev[to] == lev[x]+1 && e[i].cap){
45 int f = dfs(to,min(flow-rest , e[i].cap));
46 if(f){
47 rest += f;
48 e[i].cap -= f;
49 e[i^1].cap += f;
50 }
51 }
52 }
53 return rest;
54 }
55
56 int main(){
57 int x; cin >> n >> room >> meal;
58 s = 0; t = n*2+room+meal+1;
59 for(int i=n*2+1;i<=n*2+room;i++) add(s,i,1) , add(i,s,0);
60 for(int i=1;i<=n;i++) add(i,i+n,1) , add(i+n,i,0);
61 for(int i=n*2+room+1;i<t;i++) add(i,t,1) , add(t,i,0);
62 for(int i=1;i<=n;i++)
63 for(int j=n*2+1;j<=n*2+room;j++)
64 cin >> x , add(j,i,x) , add(i,j,0);
65 for(int i=n+1;i<=n*2;i++)
66 for(int j=n*2+room+1;j<t;j++)
67 cin >> x , add(i,j,x) , add(j,i,0);
68 while(bfs()) ans += dfs(s,inf);
69 printf("%d
",ans);
70 return 0;
71 }
另外推薦一道相似的題:教輔的組成
總結
以上是生活随笔為你收集整理的[洛谷P1402] 酒店之王的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 对身体的挣脱与自足的想象:谈阿满的小说集
- 下一篇: Excel技巧—Excel也能P图抠图