POJ 3281 Dining(最大流板子)
牛是很挑食的。每头牛都偏爱特定的食物和饮料,其他的就不吃了。
农夫约翰为他的牛做了美味的饭菜,但他忘了根据它们的喜好检查菜单。虽然他不可能喂饱所有的人,但他想让尽可能多的奶牛吃上一顿有食物和水的大餐。
农民John煮了F(1≤F≤100)种食物,准备了D(1≤D≤100)种饮料。他的每头牛(1≤N≤100)已经决定了她是吃某种食物还是喝某种饮料。农民约翰必须为每头奶牛分配一种食物和一种饮料,以使得到这两种食物的奶牛数量最大化。
每一道菜或饮料只能由一头奶牛食用。,一旦食物2型被分配给一头奶牛,其他奶牛就不能被分配食物2型。
输入
第1行:三个用空格分隔的整数:N、F和D
行2 . .N+1:每一行i以两个整数Fi和Di开头,分别是我喜欢的菜的数量和我喜欢的饮料的数量。下一个Fi整数表示我要吃的牛的盘子,后面的Di整数表示我要喝的牛的饮料。
输出
第1行:一个单一的整数,它是符合奶牛愿望的能被喂养的食物和饮料的最大数量
题意:
每一头牛有它所喜欢吃的东西和喝的东西,现在你有f种食物,d种饮料。现在你应该去用有限的食物和饮料去服务更多的牛。只有你给一头牛了一个它喜欢吃的食物和一瓶它喜欢喝的饮料,然后才算作服务了它
对于每一种牛,如果它有多种喜欢的食物,你只需要从中挑取一个就可以,不需要全部都给它安排上;饮料也是这样
题解:
st为最大流的起点,en为最大流的终点
这一道题刚拿到手确实不知道怎么用最大流来做。。。。
你可以让每一种食物和起点st建一条边,而且很明显这一条边的容量肯定是1,因为每一个食物只能给一个牛。同样让饮料和终点en建一条边。容量同样为1
这个时候还需要对n头牛进行拆点成i->start,i->last,然后对于牛喜欢吃的食物,就让食物和i->start建一条容量为1的边。对于牛喜欢喝的饮料就让i->last和饮料建一条容量为1的边
拆点的话就要在i->start和i->last之间建一条容量为1的边,用来限制每一头牛只能服务一次。如果不拆点的话可能会导致一头牛被服务了多次
毕竟建图方式不一样,有的时候拆不拆点不一定,因为我的这种方式建图如果不拆点的话一头牛就可能被服务多次
比如牛喜欢吃1 2 两个食物,喝3,4两种饮料,这样的话不拆点1可以直接通过牛和3或4相连,从而使结果加1.之后2食物还可以通过牛找另一个饮料是结果再加1.
但是如果拆点的话,因为牛与牛之间还连了一条容量为1的边,所以每一个牛就只能通过一次
当然每一条边还需要建一条它的反向边,容量为0.这条边的作用就是为了反悔。因为之前可能某物品用了这条边,但是在后面在找最有结果的时候可能这个物品不使用这条边的才是最优。这个时候就需要反向边
代码:
1 #include<stdio.h>
2 #include<string.h>
3 #include<iostream>
4 #include<algorithm>
5 #include<queue>
6 using namespace std;
7 const int maxn=10000;
8 const int INF=0x3f3f3f3f;
9 int head[maxn],cnt,st,en,dis[maxn],cur[maxn];
10 struct edge
11 {
12 int v,next,c,flow;
13 }e[maxn];
14 void add_edge(int x,int y,int z)
15 {
16 e[cnt].v=y;
17 e[cnt].c=z;
18 e[cnt].flow=0;
19 e[cnt].next=head[x];
20 head[x]=cnt++;
21 }
22 bool bfs()
23 {
24 memset(dis,0,sizeof(dis));
25 dis[st]=1;
26 queue<int>r;
27 r.push(st);
28 while(!r.empty())
29 {
30 int x=r.front();
31 r.pop();
32 for(int i=head[x];i!=-1;i=e[i].next)
33 {
34 int v=e[i].v;
35 if(!dis[v] && e[i].c>e[i].flow)
36 {
37 dis[v]=dis[x]+1;
38 r.push(v);
39 }
40 }
41 }
42 return dis[en];
43 }
44 int dinic(int s,int limit)
45 {
46 if(s==en || !limit) return limit;
47 int ans=0;
48 for(int &i=cur[s];i!=-1;i=e[i].next)
49 {
50 int v=e[i].v,feed;
51 if(dis[v]!=dis[s]+1) continue;
52 feed=dinic(v,min(limit,e[i].c-e[i].flow));
53 if(feed)
54 {
55 e[i].flow+=feed;
56 e[i^1].flow-=feed;
57 limit-=feed;
58 ans+=feed;
59 if(limit==0) break;
60 }
61 }
62 if(!ans) dis[s]=-1;
63 return ans;
64 }
65 int main()
66 {
67 memset(head,-1,sizeof(head));
68 int n,f,d;
69 scanf("%d%d%d",&n,&f,&d);
70 st=0;
71 en=2*n+f+d+1;
72 for(int i=1;i<=f;++i)
73 {
74 add_edge(st,2*n+i,1);
75 add_edge(2*n+i,st,0);
76 }
77 for(int i=1;i<=d;++i)
78 {
79 add_edge(2*n+f+i,en,1);
80 add_edge(en,2*n+f+i,0);
81 }
82 for(int i=1;i<=n;++i)
83 {
84 add_edge(i,n+i,1);
85 add_edge(n+i,i,0);
86 int sum1,sum2;
87 scanf("%d%d",&sum1,&sum2);
88 int x;
89 for(int j=0;j<sum1;++j)
90 {
91 scanf("%d",&x);
92 add_edge(x+2*n,i,1);
93 add_edge(i,x+2*n,0);
94 }
95 for(int j=0;j<sum2;++j)
96 {
97 scanf("%d",&x);
98 add_edge(n+i,x+f+2*n,1);
99 add_edge(x+f+2*n,n+i,0);
100 }
101 }//主函数从开头到这就是建图
102
103 int ans=0;
104 while(bfs())
105 {
106 for(int i=0;i<=en;i++)
107 cur[i]=head[i];
108 ans+=dinic(st,1); //这个1也可以改成无穷大
109 }
110 printf("%d\n",ans);
111 return 0;
112 }
POJ 3281 Dining(最大流板子)的更多相关文章
- POJ 3281 Dining(最大流)
POJ 3281 Dining id=3281" target="_blank" style="">题目链接 题意:n个牛.每一个牛有一些喜欢的 ...
- POJ 3281 Dining(最大流+拆点)
题目链接:http://poj.org/problem?id=3281 题目大意:农夫为他的 N (1 ≤ N ≤ 100) 牛准备了 F (1 ≤ F ≤ 100)种食物和 D (1 ≤ D ≤ 1 ...
- 【网络流#7】POJ 3281 Dining 最大流 - 《挑战程序设计竞赛》例题
不使用二分图匹配,使用最大流即可,设源点S与汇点T,S->食物->牛->牛->饮料->T,每条边流量为1,因为流过牛的最大流量是1,所以将牛拆成两个点. 前向星,Dini ...
- POJ 3281 Dining 最大流
饮料->牛->食物. 牛拆成两点. //#pragma comment(linker, "/STACK:1024000000,1024000000") #include ...
- POJ 3281 Dining ( 最大流 && 建图 )
题意 : 有 N 头牛,John 可以制作 F 种食物和 D 种饮料, 然后接下来有 N 行,每行代表一头牛的喜好==>开头两个数 Fi 和 Di 表示这头牛喜欢 Fi 种食物, Di 种饮料 ...
- POJ 3281 Dining (网络流)
POJ 3281 Dining (网络流) Description Cows are such finicky eaters. Each cow has a preference for certai ...
- poj 3281 Dining 网络流-最大流-建图的题
题意很简单:JOHN是一个农场主养了一些奶牛,神奇的是这些个奶牛有不同的品味,只喜欢吃某些食物,喝某些饮料,傻傻的John做了很多食物和饮料,但她不知道可以最多喂饱多少牛,(喂饱当然是有吃有喝才会饱) ...
- POJ 3281 Dining(最大流)
http://poj.org/problem?id=3281 题意: 有n头牛,F种食物和D种饮料,每头牛都有自己喜欢的食物和饮料,每种食物和饮料只能给一头牛,每头牛需要1食物和1饮料.问最多能满足几 ...
- 图论--网络流--最大流--POJ 3281 Dining (超级源汇+限流建图+拆点建图)
Description Cows are such finicky eaters. Each cow has a preference for certain foods and drinks, an ...
随机推荐
- 操作系统-1w字关于内存的总结
内存的基本概念 什么是内存,有何作用 内存是用于存放数据的硬件.程序执行前需要先放入内存中才能被CPU处理 存储单元 内存中也有一个一个的小房间,每个小房间就是一个存储单元. 如果计算机按照 字节编址 ...
- 【Vue】Vue框架常用知识点 Vue的模板语法、计算属性与侦听器、条件渲染、列表渲染、Class与Style绑定介绍与基本的用法
Vue框架常用知识点 文章目录 Vue框架常用知识点 知识点解释 第一个vue应用 模板语法 计算属性与侦听器 条件渲染.列表渲染.Class与Style绑定 知识点解释 vue框架知识体系 [1]基 ...
- ctfhub技能树—信息泄露—hg泄露
打开靶机 查看页面信息 使用dvcs-ripper工具进行处理 ./rip-hg.pl -v -u http://challenge-cf630b528f6f25e2.sandbox.ctfhub.c ...
- Java入门者:如何写出美观的Java代码?
前言 在帮助各位同学远程解决代码问题的时候,发现很多同学的代码都有一个共同问题:代码书写格式不规范.虽然代码书写规范对程序性能及运行并不影响,但影响着别人对你编程习惯或能力的第一印象,同时也会给阅读者 ...
- Q-Q图原理详解及Python实现
[导读]在之前的<数据挖掘概念与技术 第2章>的文章中我们介绍了Q-Q图的概念,并且通过调用现成的python函数, 画出了Q-Q图, 验证了Q-Q图的两个主要作用,1. 检验一列数据是否 ...
- canvas星空背景特效+CSS旋转相册学习
今天在看帖子的时候,看到了个有趣的css旋转相册,刚好之前做了一个星空背景dome,这里给大家分享下代码: 旋转相册参考:https://blog.csdn.net/gitchatxiaomi/art ...
- XV6学习(2)Lab syscall
实验的代码放在了Github上. 第二个实验是Lab: system calls. 这个实验主要就是自己实现几个简单的系统调用并添加到XV6中. XV6系统调用 添加系统调用主要有以下几步: 在use ...
- 删除HDFS中指定的文件。
1 import java.text.SimpleDateFormat; 2 import java.util.Scanner; 3 4 import org.apache.hadoop.fs.Fil ...
- UT /SIT/ UAT
UT /SIT/ UAT - 云+社区 - 腾讯云 https://cloud.tencent.com/developer/article/1541268 我们公司只有测试环境--准生产环境--生产环 ...
- 【转】DDD-应用架构
简介: 应用架构,指软件系统中固定不变的代码结构.设计模式.规范和组件间的通信方式.在应用开发中架构之所以是最重要的第一步,因为一个好的架构能让系统安全.稳定.快速迭代.但是今天我们在做业务研发时,更 ...