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 ...
随机推荐
- 【Linux】Linux介绍和安装 - 测试题
第一部分测试题 Linux介绍和安装 测试题 做点练习题,巩固一下咯~ ~ _ 10 个选择题. 1.让我们选择开机时进哪个操作系统的软件叫什么? A. booter B. bootloader C. ...
- kubernets之job资源
一 介绍job资源 1.1 前面介绍的RC,RS,DS等等,管控的pod都是需要长期持久的运行的应用,但是尝试考虑另外一种场景,在微服务的场景下,有些pod的作用就是需要 执行完一些命令之后正常 ...
- 开发中经常使用到的Xcode快捷键
工欲善其事必先利其器. 有了这些快捷键加持,你写代码不仅很6而且还很好看. 这些快捷键都是平时使用频率非常高的,今天整理出来分享给大家了. 左缩进:Cmd + [ 右缩进:Cmd + ] 代码格式化/ ...
- Nginx的简介和使用nginx实现请求转发
一.什么是Nginx Nginx是lgor Sysoev为俄罗斯访问量第二的rambler.ru站点设计开发的.从2004年发布至今,凭借开源的力量,已经接近成熟与完善. Nginx功能丰富,可作为H ...
- kafka项目经验之如何进行Kafka压力测试、如何计算Kafka分区数、如何确定Kaftka集群机器数量
@ 目录 Kafka压测 Kafka Producer(生产)压力测试 Kafka Consumer(消费)压力测试 计算Kafka分区数 Kafka机器数量计算 Kafka压测 用Kafka官方自带 ...
- CTO也糊涂的常用术语:功能模块、业务架构、用户需求、文档……
功能模块.业务架构.需求分析.用户需求.系统分析.功能设计.详细设计.文档.业务.技术--很多被随口使用的名词,其实是含糊甚至错误的. 到底含糊在哪里,错误在哪里,不仅仅是新手软件开发人员糊涂,许多入 ...
- Cisco发现协议
CDP Cisco Discovery Protocol: 思科发现协议 是一个提供关于直接相连的交换机.路由器和其它Cisco设备的综合信息的专有工具 CDP 能够发现直接相邻的设备而不管这些设备所 ...
- Windows 2008server部署pxe启动安装windows系统
前期准备: 需安装的角色有:AD域-DHCP服务器-DNS服务器-Windows部署服务,我是将这几个服务都安装在一台vps上,C盘50G,D盘100G 安装好后角色会列出所安装的服务,如下图: 1. ...
- 从tcp层面研究java socket 的使用
本文主要通过wireshark抓包来分析java socket程序的一些细节, 解决以前的一些疑问: 1.当一方的socket先关闭后,另一方尚未关闭的socket 还能做什么? 2.当基于socke ...
- 【Android初级】教你用两行代码实现“显示/隐藏密码”的效果
Android里面要使用密码的场景是非常多的,支付宝.微信.淘宝以及各大银行APP,都跟用户的密码有关.用户的密码是极为隐私的,用户在输入时不希望密码被别人看到,所以几乎所有需要输入密码的场景下都会把 ...