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 ...
随机推荐
- 详细的String源码解析
我们常常把String类型的字符串作为HashMap的key,为什么要这样做呢? 因为String是不可变的,一旦初始化就不再改变了,如果被修改将会是一个新对象. @Test public void ...
- 70.LeetCode爬楼梯
爬楼梯 点击标题可跳转到官网进行查看 假设你正在爬楼梯.需要 n 阶你才能到达楼顶. 每次你可以爬 1 或 2 个台阶.你有多少种不同的方法可以爬到楼顶呢? 注意:给定 n 是一个正整数. 示例 1: ...
- 十六:SQL注入之查询方式及报错盲注
在很多注入时,有很多注入会出现无回显的情况,其中不回显的原因可能是SQL查询语句有问题,这时候我们需要用到相关的报错或者盲注进行后续操作,同时作为手工注入的时候,需要提前了解SQL语句能更好的选择对应 ...
- (十六)re模块
正则表达式并不是Python的一部分,本质而言,正则表达式(或 RE)是一种小型的.高度专业化的编程语言.正则表达式是用于处理字符串的强大工具,很多编程语言都支持正则表达式的语法. 字符匹配分为普通字 ...
- XEE - Pikachu
概述 XXE -"xml external entity injection"既"xml外部实体注入漏洞".概括一下就是"攻击者通过向服务器注入指定的 ...
- Databricks 第7篇:管理Secret
有时,访问数据要求您通过JDBC对外部数据源进行身份验证,可以使用Azure Databricks Secret来存储凭据,并在notebook和job中引用它们,而不是直接在notebook中输入凭 ...
- rbd-db数据迁移至外部数据库
部署外部数据库 安装Docker export VERSION=19.03 && curl -fsSL http://rainbond-pkg.oss-cn-shanghai.aliy ...
- Python+Selenium+Unittest实现PO模式web自动化框架(2)
1.Common目录下的具体模块讲解. 2.basepage.py basepage.py模块里面是封装的对元素的操作.例如:查找元素.点击元素.文本输入等等. # --^_^-- coding:ut ...
- Cmder的findstr问题
在环境变量中加入C:\windows\system32即可
- MarkDown学习笔记 Typora
快捷方式篇 新建 ctrl + N 新建窗口 ctrl + shift + N 打开md文件 ctrl + O 快速打开 ctrl + P 保存 ctrl + S 另存为 ctrl + shift + ...