Dining

 Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 17414 Accepted: 7728

Description

Cows are such finicky eaters. Each cow has a preference for certain foods and drinks, and she will consume no others.

Farmer John has cooked fabulous meals for his cows, but he forgot to check his menu against their preferences. Although he might not be able to stuff everybody, he wants to give a complete meal of both food and drink to as many cows as possible.

Farmer John has cooked F (1 ≤ F ≤ 100) types of foods and prepared D (1 ≤ D ≤ 100) types of drinks. Each of his N (1 ≤ N ≤ 100) cows has decided whether she is willing to eat a particular food or drink a particular drink. Farmer John must assign a food type and a drink type to each cow to maximize the number of cows who get both.

Each dish or drink can only be consumed by one cow (i.e., once food type 2 is assigned to a cow, no other cow can be assigned food type 2).

Input

Line 1: Three space-separated integers: N, F, and D
Lines 2.. N+1: Each line i starts with a two integers Fi and Di, the number of dishes that cow i likes and the number of drinks that cow i likes. The next Fi integers denote the dishes that cow i will eat, and the Di integers following that denote the drinks that cow i will drink.

Output

Line 1: A single integer that is the maximum number of cows that can be fed both food and drink that conform to their wishes

Sample Input

4 3 3
2 2 1 2 3 1
2 2 2 3 1 2
2 2 1 3 1 2
2 1 1 3 3

Sample Output

3

Hint

One way to satisfy three cows is:
Cow 1: no meal
Cow 2: Food #2, Drink #2
Cow 3: Food #1, Drink #1
Cow 4: Food #3, Drink #3
The pigeon-hole principle tells us we can do no better since there are only three kinds of food or drink. Other test data sets are more challenging, of course.

Source

思路:最大流+拆点
F->N->N->D
代码实现:
 1 #include<cstdio>
 2 #include<cstring>
 3 const int maxn=500;
 4 const int maxm=1e6;
 5 int n,f,d,s,t,ans;
 6 int a,b,c;
 7 inline int min_(int x,int y){return x<y?x:y;}
 8 int h[maxn],hs=1;
 9 int e_s[maxm],e_w[maxm],e_n[maxm];
10 void add(int q,int z){
11     ++hs,e_s[hs]=z,e_w[hs]=1,e_n[hs]=h[q],h[q]=hs;
12     ++hs,e_s[hs]=q,e_n[hs]=h[z],h[z]=hs;
13 }
14 int de[maxn],q[maxn],head,tail;
15 void bfs(){
16     memset(de,0,sizeof(de));
17     head=tail=0;
18     de[s]=1,q[head++]=s;
19     while(head>tail){
20         a=q[tail++];
21         for(int i=h[a];i;i=e_n[i])
22         if(!de[e_s[i]]&&e_w[i]){
23             de[e_s[i]]=de[a]+1;
24             if(e_s[i]==t) return;
25             q[head++]=e_s[i];
26         }
27     }
28 }
29 int ap(int k,int nw){
30     if(k==t) return nw;
31     int bw=nw;
32     for(int i=h[k];i&&bw;i=e_n[i])
33     if(e_w[i]&&de[e_s[i]]==de[k]+1){
34         int dw=ap(e_s[i],min_(bw,e_w[i]));
35         if(dw) e_w[i]-=dw,e_w[i^1]+=dw,bw-=dw;
36         else de[e_s[i]]=0;
37     }
38     return nw-bw;
39 }
40 void Dinic(){while(bfs(),de[t]) ans+=ap(s,0xffffff);}
41 int main(){
42     scanf("%d%d%d",&n,&f,&d);
43     s=0,t=f+n+n+d+1;
44     for(int i=1;i<=f;i++) add(s,i);
45     for(int i=1;i<=n;i++) add(f+i,f+n+i);
46     for(int i=1;i<=d;i++) add(f+n+n+i,t);
47     for(int i=1;i<=n;i++){
48         scanf("%d%d",&a,&b);
49         for(int j=1;j<=a;j++){
50             scanf("%d",&c);
51             add(c,f+i);
52         }
53         for(int j=1;j<=b;j++){
54             scanf("%d",&c);
55             add(f+n+i,f+n+n+c);
56         }
57     }
58     Dinic();
59     printf("%d",ans);
60     return 0;
61 }

1A但是是比着自己最大流的模板打的。

转载于:https://www.cnblogs.com/J-william/p/6790201.html

### Dining Philosophers Problem 概述 Dining Philosophers Problem 是由 Edsger Dijkstra 提出的经典同步问题,用于描述并发编程中的资源竞争和死锁现象[^1]。该问题设定如下: 五个哲学家围坐在一张圆桌旁,每位之间放置一根筷子。为了吃饭,每名哲学家需要同时拿起左边和右边的两根筷子。 ### 实现方式与挑战 主要挑战在于如何设计算法来防止死锁的发生,即避免所有哲学家都只拿到一根筷子而陷入无限等待的状态。常见的解决方法有多种变体,包括但不限于: #### 方法一:奇偶策略 通过规定只有当编号为奇数的哲学家先拿左侧筷子,偶数则相反的方式减少冲突的可能性。 ```python import threading class Chopstick: def __init__(self, index): self.index = index self.lock = threading.Lock() def philosopher(index, left_chopstick, right_chopstick): while True: if index % 2 == 0: with left_chopstick.lock: with right_chopstick.lock: eat() else: with right_chopstick.lock: with left_chopstick.lock: eat() ``` #### 方法二:引入仲裁者 设置一个额外的服务进程作为监督者,在分配筷子前检查是否有足够的资源可供使用,从而预防潜在的死锁情况发生。 ```python import queue chopsticks_queue = queue.Queue(maxsize=5) for i in range(5): chopsticks_queue.put(i) def supervised_philosopher(id_, supervisor): while True: first = id_ second = (id_ + 1) % 5 supervisor.acquire([first, second]) try: eat() finally: supervisor.release([first, second]) ``` ### 解决方案总结 上述两种方法各有优劣,前者简单易懂但可能造成饥饿;后者虽然能有效避免死锁却增加了系统的复杂度。实际应用中可根据具体需求权衡选择最合适的方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值