kuangbin专题专题十一 网络流 Dining POJ - 3281

题目链接:https://vjudge.net/problem/POJ-3281

题目:有不同种类的食物和饮料,每种只有1个库存,有N头牛,每头牛喜欢某些食物和某些饮料,但是一头牛

只能吃一种食物和喝一种饮料,问怎么分配食物和饮料才能让最多数量的牛饱餐。

思路:容易想到  食物->牛->饮料的流,当然一个牛可以被多个饮料流到,需要把牛拆成入点和出点,入点和出点流量为1,这样可以保证牛只吃或者喝某种食物和饮料,别的都流是套路,除了牛的分点之间流量为1,别的连接设置成1或者INF都一样,因为有牛的分点流量的限制。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <queue>
  5 using namespace std;
  6
  7 const int N = 410,INF = (int)1e9;
  8 int n,F,D,tot,S,T;
  9 int head[N],lev[N];
 10 queue<int > que;
 11 struct node{
 12     int to,nxt,flow;
 13 }e[N*N];
 14
 15 inline void add(int u,int v,int flow){
 16     e[tot].to = v;
 17     e[tot].flow = flow;
 18     e[tot].nxt = head[u];
 19     head[u] = tot++;
 20     e[tot].to = u;
 21     e[tot].flow = 0;
 22     e[tot].nxt = head[v];
 23     head[v] = tot++;
 24 }
 25
 26 void build_map(int s,int t){
 27
 28     for(int i = s; i <= t; ++i) head[i] = -1; tot = 0;
 29     //读入信息  0是源点 1~F食物 F+1~F+2*n牛 F+2*n+1~F+2*n+D饮料 F+2*n+D+1是汇点
 30     int kind_f,kind_d,x;
 31     for(int i = 1; i <= n; ++i){
 32         scanf("%d%d",&kind_f,&kind_d);
 33         for(int j = 1; j <= kind_f; ++j){
 34             scanf("%d",&x);
 35             add(x,F+i,1);// add(F+i,x,0);
 36         }
 37         for(int j = 1; j <= kind_d; ++j){
 38             scanf("%d",&x);
 39             add(F+n+i,F+2*n+x,1);// add(F+2*n+x,F+n+i,0);
 40         }
 41     }
 42     for(int i = 1; i <= F; ++i){
 43         add(s,i,1);// add(i,s,0);
 44     }
 45     for(int i = 1; i <= D; ++i){
 46         add(F+2*n+i,t,1);// add(t,F+2*n+i,0);
 47     }
 48     for(int i = 1; i <= n; ++i){
 49         add(F+i,F+n+i,1);// add(F+n+i,F+i,0);
 50     }
 51 }
 52
 53 void show(int s,int t){
 54     for(int i = s; i <= t; ++i){
 55         cout << "当前点为 " << i << "    ";
 56         cout << "能去到 ";
 57         for(int o = head[i]; ~o; o = e[o].nxt){
 58             printf("  %d 流量为 %d",e[o].to,e[o].flow);
 59         }cout << endl;
 60     }
 61 }
 62
 63 bool bfs(int s,int t){
 64     while(!que.empty()) que.pop();
 65     for(int i = s; i <= t; ++i) lev[i] = 0;
 66     lev[s] = 1;
 67     que.push(s);
 68     while(!que.empty()){
 69         int u = que.front(); que.pop();
 70         for(int o = head[u]; ~o; o = e[o].nxt){
 71             int v = e[o].to;
 72             if(!lev[v] && e[o].flow ){
 73                 lev[v] = lev[u] + 1;
 74                 if(v == t) return true;
 75                 que.push(v);
 76             }
 77         }
 78     }
 79     return false;
 80 }
 81
 82 int dfs(int now,int flow,int t){
 83     if(now == t) return flow;
 84     int to,sum = 0,tmp;
 85     for(int o = head[now]; ~o; o = e[o].nxt){
 86         to = e[o].to;
 87         if((lev[to] == lev[now] + 1) && e[o].flow && (tmp = dfs(to,min(flow-sum,e[o].flow),t))){
 88             e[o].flow -= tmp;
 89             e[o^1].flow += tmp;
 90             if((sum += tmp) == flow) return sum;
 91         }
 92     }
 93     return sum;
 94 }
 95
 96 int mf(int s,int t){
 97     int _mf = 0;
 98     while(bfs(s,t)){
 99         _mf += dfs(s,INF,t);
100     }
101     return _mf;
102 }
103
104 int main(){
105
106     scanf("%d%d%d",&n,&F,&D);
107     S = 0; T = F+2*n+D+1;
108     //建图
109     build_map(S,T);
110    // show(S,T); //图的显示
111     int ans = mf(S,T);
112     printf("%d\n",ans);
113
114     return 0;
115 }

原文地址:https://www.cnblogs.com/SSummerZzz/p/12241735.html

时间: 2024-11-05 22:43:43

kuangbin专题专题十一 网络流 Dining POJ - 3281的相关文章

B - Dining POJ - 3281 网络流

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

Dining POJ - 3281(最大流)

Dining Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 25452   Accepted: 11183 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 fabul

AC日记——Dining poj 3281

[POJ-3281] 思路: 把牛拆点: s向食物连边,流量1: 饮料向t连边,流量1: 食物向牛1连边,流量1: 牛2向饮料连边,流量1: 最大流: 来,上代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define maxn 2005 #define INF 0x7fffffff int n,f,

kuangbin专题专题四 Til the Cows Come Home POJ - 2387

题目链接:https://vjudge.net/problem/POJ-2387 题意:从编号为n的城市到编号为1的城市的最短路. 思路:dijkstra模板题,直接套板子,代码中我会带点注释给初学者看. 1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #include <cstdio> 5 #include <string> 6 using namespac

POJ 3281 Dining(网络最大流)

http://poj.org/problem?id=3281 Dining Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9121   Accepted: 4199 Description Cows are such finicky eaters. Each cow has a preference for certain foods and drinks, and she will consume no others.

poj 3281 Dining(最大流)

poj 3281 Dining 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 prefer

POJ 3281 Dining(最大流建图 &amp;&amp; ISAP &amp;&amp; 拆点)

题目链接:http://poj.org/problem?id=3281 努力练建图ing!!! 题意:有 N 头牛,有 F 种食物和 D 种饮料,每种食物或饮料只能供一头牛享用,且每头牛只享用一种食物和一种饮料. 第2行-第N+1行.是牛i 喜欢A种食物,B种饮料,及食物种类列表和饮料种类列表. 问最多能使几头牛同时享用到自己喜欢的食物和饮料.->最大流. 本题难点是建图: 思路:一般都是左边一个集合表示源点与供应相连,右边一个集合表示需求与汇点相连. 但是本题,牛作为需求仍然是一个群体,但是供

POJ 3281 Dining(最大流)

POJ 3281 Dining 题目链接 题意:n个牛,每个牛有一些喜欢的食物和饮料,每种食物饮料只有一个,问最大能匹配上多少只牛每个牛都能吃上喜欢的食物和喜欢的饮料 思路:最大流,建模源点到每个食物连一条边,容量为1,每个饮料向汇点连一条边容量为1,然后由于每个牛有容量1,所以把牛进行拆点,然后食物连向牛的入点,牛的出点连向食物,跑一下最大流即可 代码: #include <cstdio> #include <cstring> #include <queue> #in

POJ 3281 网络流dinic算法

B - Dining Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 3281 Appoint description: Description Cows are such finicky eaters. Each cow has a preference for certain foods and drinks, and she wil