POJ 3281 Dining (拆点)【最大流】
<题目链接>
题目大意:
有N头牛,F种食物,D种饮料,每一头牛都有自己喜欢的食物和饮料,且每一种食物和饮料都只有一份,让你分配这些食物和饮料,问最多能使多少头牛同时获得自己喜欢的食物和饮料。
解题分析:
开始还以为是一道匹配问题,后面才知道这是用网络流求解。
首先我们要明确,如果按照源点——>食物——>牛——>饮料——>汇点这样建图,是不符合题目条件的。因为题目要求每头牛只能吃一份食物和饮料,而这样建图,如果一头牛对应多个食物和饮料,那这样那头牛是可以吃多份食物和饮料的,所以我们需要对牛进行拆点,并且拆除的两点之间用容量为1边相连,这样跑最大流的时候就能够限制每头牛最多只能吃一份食物和饮料了。下面是Dinic的模板。
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
#define INF 0x3f3f3f3f
;
const int maxm = 1e5;
int depth[maxn], vis[maxn],cur[maxn], head[maxn];
int N, F, D;
int sect,cnt; //sect为汇点
struct Edge {
int v, cap, flow, next;
}edge[maxm];
void init(){
cnt = ;
memset(head, -, sizeof(head));
}
void add(int u, int v, int w){
edge[cnt].v = v, edge[cnt].cap = w, edge[cnt].flow = ,edge[cnt].next = head[u]; //正向弧(容量为w)
head[u] = cnt++;
edge[cnt].v = u, edge[cnt].cap = , edge[cnt].flow = ,edge[cnt].next = head[v]; //反向弧(容量为0)
head[v] = cnt++;
}
void getmap(){
int tmp1, tmp2;
; i <= N; ++i){
scanf("%d%d", &tmp1, &tmp2);
while(tmp1--){
int num;
scanf("%d", &num);
add( * N + num, i, );//食物和左牛连接
}
while(tmp2--){
int num;
scanf("%d", &num);
add(N + i, * N + F + num, );//右牛和饮料连接
}
add(i, i + N, );//左牛和右牛连接
}
sect = * N + F + D + ;
; i <= F; ++i)
add(, * N + i, );//源点和食物连接
; i <= D; ++i)
add( * N + F + i, * N + F + D + , );//饮料和超级汇点连接
}
bool BFS(int st, int ed){ //构建分层图,并且判断增广路径是否存在
queue<int>q;
memset(depth, -, sizeof(depth)); //将所有点分层,初始化深度为-1
memset(vis, ,sizeof(vis));
q.push(st);
depth[st] = ; //源点深度为0
vis[st] = ;
while(!q.empty()){
int u = q.front();
q.pop();
; i = edge[i].next){
Edge &E = edge[i];
if(!vis[E.v] && E.cap > E.flow){
vis[E.v] = ;
depth[E.v] = depth[u] + ; //下一个点是当前点的深度+1
if(E.v == ed) return true; //找到汇点则直接返回
q.push(E.v);
}
}
}
return false; //没有找到通向汇点的增广路径
}
int DFS(int x, int ed, int val){
)
return val;
, f;
; i = edge[i].next){ //注意这里的&符号,这样i增加的同时也能改变cur[u]的值,达到更新当前弧的目的
Edge E=edge[i];
&& (f = DFS(E.v, ed, min(val, E.cap - E.flow))) > ){ //f为残余网络中增广路径的最小残量
edge[i].flow += f; //进行增广
edge[i ^ ].flow -= f; //正向流量+f,相当于反向流量-f
flow += f;
val -= f;
) break;
}
}
return flow;
}
int Dinic(int st, int ed){
; //最大流
while(BFS(st, ed)){ //判断是否存在增广路
memcpy(cur, head, sizeof(head)); //当前弧优化
sumflow += DFS(st, ed, INF);
}
return sumflow;
}
int main (){
while(scanf("%d%d%d", &N, &F, &D) != EOF){
init();
getmap(); //建图
printf(, sect));
}
;
}
2018-11-23
POJ 3281 Dining (拆点)【最大流】的更多相关文章
- poj 3281 Dining 拆点 最大流
题目链接 题意 有\(N\)头牛,\(F\)个食物和\(D\)个饮料.每头牛都有自己偏好的食物和饮料列表. 问该如何分配食物和饮料,使得尽量多的牛能够既获得自己喜欢的食物又获得自己喜欢的饮料. 建图 ...
- POJ 3281 Dining (网络流之最大流)
题意:农夫为他的 N (1 ≤ N ≤ 100) 牛准备了 F (1 ≤ F ≤ 100)种食物和 D (1 ≤ D ≤ 100) 种饮料.每头牛都有各自喜欢的食物和饮料, 而每种食物或饮料只能分配给 ...
- POJ 3281 Dining(最大流)
POJ 3281 Dining id=3281" target="_blank" style="">题目链接 题意:n个牛.每一个牛有一些喜欢的 ...
- 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 网络流 拆点保证本身只匹配一对食物和饮料
如何建图? 最开始的问题就是,怎么表示一只牛有了食物和饮料呢? 后来发现可以先将食物与牛匹配,牛再去和饮料匹配,实际上这就构成了三个层次. 起点到食物层边的容量是1,食物层到奶牛层容量是1,奶牛层到饮 ...
- POJ 3281 Dining(最大流+拆点)
题目链接:http://poj.org/problem?id=3281 题目大意:农夫为他的 N (1 ≤ N ≤ 100) 牛准备了 F (1 ≤ F ≤ 100)种食物和 D (1 ≤ D ≤ 1 ...
- 图论--网络流--最大流--POJ 3281 Dining (超级源汇+限流建图+拆点建图)
Description Cows are such finicky eaters. Each cow has a preference for certain foods and drinks, an ...
- POJ 3281 Dining(网络流拆点)
[题目链接] http://poj.org/problem?id=3281 [题目大意] 给出一些食物,一些饮料,每头牛只喜欢一些种类的食物和饮料, 但是每头牛最多只能得到一种饮料和食物,问可以最多满 ...
随机推荐
- js模块化编程之CommonJS和AMD/CMD
js模块化编程commonjs.AMD/CMD与ES6模块规范 一.CommonJS commonjs的require是运行时同步加载,es6的import是静态分析,是在编译时而不是在代码运行时.C ...
- Jquery无刷新实时更新表格数据
html代码: <style> .editbox { display:none } .editbox { font-size:14px; width:70px; background-co ...
- mysql 安装问题三:FATAL ERROR: please install the following Perl modules before executing ./scripts/mysql_install_db: Data::Dumper
解决方法是安装autoconf库,执行命令:yum -y install autoconf 安装完成之后继续执行安装mysql的命令:./scripts/mysql_install_db --user ...
- js中的“==”和“===”的区别
简单来说: == 代表相同, ===代表严格相同, 为啥这么说呢, 这么理解: 当进行双等号比较时候: 先检查两个操作数数据类型,如果相同, 则进行===比较, 如果不同, 则愿意为你进行一次类型转换 ...
- 刚发了两个关于极光推送的网上Demo,再次自己结合官网总结一下,以便加深印象
简单源码如下: //Map<String, String> parm是我自己传过来的参数,同学们可以自定义参数public static void jpushAndroid(Map< ...
- 论文阅读笔记六:FCN:Fully Convolutional Networks for Semantic Segmentation(CVPR2015)
今天来看一看一个比较经典的语义分割网络,那就是FCN,全称如题,原英文论文网址:https://people.eecs.berkeley.edu/~jonlong/long_shelhamer_fcn ...
- 集腋成裘-03-css基础-02
1.1 三种写法 内嵌式:样式只作用于当前文件,没有真正实现结构表现分离 外链式:作用范围是当前站点,真正实现了内容与表现分离 行内样式:仅限于当前标签,结构混在一起 1.2 标签分类 1.2.1 块 ...
- The.Glory.of.Innovation 创新之路3放飞好奇
教育最重要的就是 问题不在于教他各种学问,而在于培养他爱好学问的兴趣,而且在这种兴趣充分增长起来的时候,教他以研究学问的方法. ———— 卢梭 如何辨识不同的观点, 老师考查的重点不在于学生 ...
- azkaban安装使用
本文记录azkaban的安装和 一些报错处理(文章末尾). AzKaban组成 MySQL数据库,azkaban-server (web端),azkaban-executor (执行job) 1.下载 ...
- 从零开始学C#——不再更新,直接进入高阶教程
从零开始学习C#不再更新,直接进入高阶教程. 入门教程,请自行谷歌.百度吧,有很多这样的教程. 编程是一件实践性很强的事情,那么接下来的文章将开始进行开发项目. 还在编程中迷茫的人们,先暂时放下一切的 ...