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 ...
随机推荐
- Python利用最优化算法求解投资内部收益率IRR【一】
一. 内部收益率和净现值 内部收益率(Internal Rate of Return, IRR)其实要和净现值(Net Present Value, NPV)结合起来讲.净现值指的是某个投资项目给公司 ...
- Pandas 常见操作详解
Pandas 常见操作详解 很多人有误解,总以为Pandas跟熊猫有点关系,跟gui叔创建Python一样觉得Pandas是某某奇葩程序员喜欢熊猫就以此命名,简单介绍一下,Pandas的命名来自于面板 ...
- dblink查找对应的目标端session
v$session试图中process字段代表的是客户端所在机器的进程号 例如我使用toad连接数据库,查询到的process即toad的进程号 SELECT process FROM V$SESSI ...
- Api文档自动生成工具
java开发,根据代码自动生成api接口文档工具,支持RESTful风格,今天我们来学一下api-doc的生成 作者:互联网编程. 欢迎投稿,一起交流技术 https://www.jianshu.co ...
- JavaWeb三大框架基础架构——CRUD的基础功能搭建
@ 目录 介绍 注意 applicationContext.xml mybatis-config.xml web.xml 结束语 介绍 项目前端采用了bootstrap,后端是ssm三大框架 注意 这 ...
- mdns
mdns mdns_百度百科 https://baike.baidu.com/item/mdns 在计算机网络中 , 多播DNS ( mDNS )协议将主机名解析为不包含本地名称服务器的小型网络中的I ...
- RPM 和YUM总结
RPM RPM命名: 安装 rpm -ihv 其他常用的选项: 1. 重新安装 --replacepkgs (或者 --force ) 2. 不考虑依赖 --nodeps (不推荐) 升级: 查询: ...
- jsaper子报表Subreport(父子报表互相传值)
有很多人都说Jasperreports不适合中国式复杂报表,实际上运用好父子报表可以解决大部分问题了.例如下面的表.每个学生的学科数目不固定,且每个学生后有相当于小计的平均分.有点复杂度的报表,可以使 ...
- 洛谷P2573
Description \(n\) 个点,有各自的高度. \(m\) 条道路,有各自的长度,每条可连接两个点. 规定只能从高点走向低点,可以回到原来的某个位置走不同的道路. 求在行走道路尽量短的情况下 ...
- Java项目开发流程()
1项目启动 2需求调研 3系统设计详细设计 4程序开发 5测试 6试用培训维护 项目成员组成 1需求工程师其要求 2系统分析师设计师其要求 3开发工程师其要求 4测试工程师其要求 5管理人员 6其他人 ...