牛是很挑食的。每头牛都偏爱特定的食物和饮料,其他的就不吃了。

农夫约翰为他的牛做了美味的饭菜,但他忘了根据它们的喜好检查菜单。虽然他不可能喂饱所有的人,但他想让尽可能多的奶牛吃上一顿有食物和水的大餐。

农民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(最大流板子)的更多相关文章

  1. POJ 3281 Dining(最大流)

    POJ 3281 Dining id=3281" target="_blank" style="">题目链接 题意:n个牛.每一个牛有一些喜欢的 ...

  2. POJ 3281 Dining(最大流+拆点)

    题目链接:http://poj.org/problem?id=3281 题目大意:农夫为他的 N (1 ≤ N ≤ 100) 牛准备了 F (1 ≤ F ≤ 100)种食物和 D (1 ≤ D ≤ 1 ...

  3. 【网络流#7】POJ 3281 Dining 最大流 - 《挑战程序设计竞赛》例题

    不使用二分图匹配,使用最大流即可,设源点S与汇点T,S->食物->牛->牛->饮料->T,每条边流量为1,因为流过牛的最大流量是1,所以将牛拆成两个点. 前向星,Dini ...

  4. POJ 3281 Dining 最大流

    饮料->牛->食物. 牛拆成两点. //#pragma comment(linker, "/STACK:1024000000,1024000000") #include ...

  5. POJ 3281 Dining ( 最大流 && 建图 )

    题意 : 有 N 头牛,John 可以制作 F 种食物和 D 种饮料, 然后接下来有 N 行,每行代表一头牛的喜好==>开头两个数 Fi 和 Di 表示这头牛喜欢 Fi 种食物, Di  种饮料 ...

  6. POJ 3281 Dining (网络流)

    POJ 3281 Dining (网络流) Description Cows are such finicky eaters. Each cow has a preference for certai ...

  7. poj 3281 Dining 网络流-最大流-建图的题

    题意很简单:JOHN是一个农场主养了一些奶牛,神奇的是这些个奶牛有不同的品味,只喜欢吃某些食物,喝某些饮料,傻傻的John做了很多食物和饮料,但她不知道可以最多喂饱多少牛,(喂饱当然是有吃有喝才会饱) ...

  8. POJ 3281 Dining(最大流)

    http://poj.org/problem?id=3281 题意: 有n头牛,F种食物和D种饮料,每头牛都有自己喜欢的食物和饮料,每种食物和饮料只能给一头牛,每头牛需要1食物和1饮料.问最多能满足几 ...

  9. 图论--网络流--最大流--POJ 3281 Dining (超级源汇+限流建图+拆点建图)

    Description Cows are such finicky eaters. Each cow has a preference for certain foods and drinks, an ...

随机推荐

  1. 关于使用th:text获取不到值

    今天在使用thymeleaf模板引擎整合SpringBoot时,对于从controller层传递过来的参数"message",无法获取. 控制层代码如下: @PostMapping ...

  2. K8s 平台可以如何处理 Pod 预授权问题

    前言 TKEx-CSIG 是基于腾讯公有云 TKE 和 EKS 容器服务开发的内部上云容器服务平台,为解决公司内部容器上云提供云原生平台,以兼容云原生.适配自研业务.开源协同为最大特点. 业务容器上云 ...

  3. 【Linux】用yum来下载rpm,而不安装

    方法一:yum yum命令本身就可以用来下载一个RPM包,标准的yum命令提供了--downloadonly(只下载)的选项来达到这个目的. $ sudo yum install --download ...

  4. golang语言初体验

    Go(又称 Golang)是 Google 的 Robert Griesemer,Rob Pike 及 Ken Thompson 开发的一种静态强类型.编译型语言.Go 语言语法与 C 相近,但功能上 ...

  5. Mysql--由prepared sql statement引发的问题

    问题回顾 最近生产环境数据库查询接口异常,抛出异常信息表明预处理sql语句声明已经超过mysql系统设置限制max_prepared_stmt_count:通过网上一些资料,分析大概是程序中数据库查询 ...

  6. the7主题 一个强大的wordpress 主题 html5拖拽式建站系统

    演示地址 http://the7.net The7汉化主题.可视化编辑器和终极交互式模块插件完全无缝集成,可以让你完全自由的布局或者创意实现你的网站,真正的建站仿站利器. The7的750+个主题设置 ...

  7. Atlas 2.1.0 实践(3)—— Atlas集成HIve

    Atlas集成Hive 在安装好Atlas以后,如果想要使用起来,还要让Atlas与其他组件建立联系. 其中最常用的就是Hive. 通过Atlas的架构,只要配置好Hive Hook ,那么每次Hiv ...

  8. 错误捕捉过滤器 .NetCore版

    前言 继承ExceptionFilterAttribute后,重写OnException函数. 统一捕捉所有报错,格式化返回前端. 代码实现 基类控制器 在基类控制器上添加[ErrorCatch]特性 ...

  9. Python爬虫学习笔记(三)

    Cookies: 以抓取https://www.yaozh.com/为例 Test1(不使用cookies): 代码: import urllib.request # 1.添加URL url = &q ...

  10. MySQL时间格式转换函数

    MySQL DATE_FORMAT() 函数注:当前年份是2018-7-19 SELECT DATE_FORMAT(NOW(),'%Y')                                ...