题意:

有F种食物和D种饮料,每头牛有各自喜欢的食物和饮料,而且每种食物或者饮料只能给一头牛。

求最多能有多少头牛能同时得到它喜欢的食物或者饮料。

分析:

把每个牛拆点,中间连一条容量为1的边,保证一头牛不会被多个食物或者饮料分配。

然后把饮料和牛连边,食物和另外一边的牛连边,最后增加一个源点和汇点跑最大流。

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std; const int maxn = + ;
const int maxnode = + ;
const int INF = 0x3f3f3f3f; int N, F, D; int n, s, t; struct Edge
{
int from, to, cap, flow;
Edge(int u, int v, int c, int f):from(u), to(v), cap(c), flow(f) {}
}; vector<Edge> edges;
vector<int> G[maxnode]; void init()
{
edges.clear();
for(int i = ; i < n; i++) G[i].clear();
} void AddEdge(int u, int v, int c)
{
edges.push_back(Edge(u, v, c, ));
edges.push_back(Edge(v, u, , ));
int m = edges.size();
G[u].push_back(m - );
G[v].push_back(m - );
} bool vis[maxnode];
int d[maxnode];
int cur[maxnode]; bool BFS()
{
d[s] = ;
queue<int> Q;
Q.push(s);
memset(vis, false, sizeof(vis));
vis[s] = true; while(!Q.empty())
{
int u = Q.front(); Q.pop();
for(int i = ; i < G[u].size(); i++)
{
Edge& e = edges[G[u][i]];
int v = e.to;
if(!vis[v] && e.cap > e.flow)
{
vis[v] = true;
d[v] = d[u] + ;
Q.push(v);
}
}
} return vis[t];
} int DFS(int u, int a)
{
if(u == t || a == ) return a;
int flow = , f;
for(int& i = cur[u]; i < G[u].size(); i++)
{
Edge& e = edges[G[u][i]];
int v = e.to;
if(d[v] == d[u] + && (f = DFS(v, min(a, e.cap - e.flow))) > )
{
flow += f;
e.flow += f;
a -= f;
edges[G[u][i]^].flow -= f;
if(a == ) break;
}
}
return flow;
} int Maxflow()
{
int flow = ;
while(BFS())
{
memset(cur, , sizeof(cur));
flow += DFS(s, INF);
}
return flow;
} int main()
{
while(scanf("%d%d%d", &N, &F, &D) == )
{
n = N * + D + F + ;
s = , t = n - ;
init(); //build graph
for(int i = ; i <= F; i++) AddEdge(s, N*+i, );
for(int i = ; i <= D; i++) AddEdge(N*+F+i, t, );
for(int i = ; i <= N; i++) AddEdge(i, i + N, ); for(int i = ; i <= N; i++)
{
int f, d, x; scanf("%d%d", &f, &d);
while(f--)
{
scanf("%d", &x);
AddEdge(N*+x, i, );
}
while(d--)
{
scanf("%d", &x);
AddEdge(N + i, N*+F+x, );
}
} printf("%d\n", Maxflow());
} return ;
}

代码君

POJ 3281 网络流 拆点 Dining的更多相关文章

  1. POJ 3281 网络流 拆点保证本身只匹配一对食物和饮料

    如何建图? 最开始的问题就是,怎么表示一只牛有了食物和饮料呢? 后来发现可以先将食物与牛匹配,牛再去和饮料匹配,实际上这就构成了三个层次. 起点到食物层边的容量是1,食物层到奶牛层容量是1,奶牛层到饮 ...

  2. poj 3281(网络流+拆点)

    题目链接:http://poj.org/problem?id=3281 思路:设一个超级源点和一个超级汇点,源点与食物相连,饮料与汇点相连,然后就是对牛进行拆点,一边喜欢的食物相连,一边与喜欢的饮料相 ...

  3. POJ 3281 网络流dinic算法

    B - Dining Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit S ...

  4. B - Dining POJ - 3281 网络流

    Cows are such finicky eaters. Each cow has a preference for certain foods and drinks, and she will c ...

  5. ACM Computer Factory POJ - 3436 网络流拆点+路径还原

    http://poj.org/problem?id=3436 每台电脑有$p$个组成部分,有$n$个工厂加工电脑. 每个工厂对于进入工厂的半成品的每个组成部分都有要求,由$p$个数字描述,0代表这个部 ...

  6. POJ 3281 网络流

    题意: 思路: 网络流 重在建图- 建完了图 就一切都好说了 这道题 我的想法是 先把源点和所有的食品连上边 (容量为1) 再把食品和对应的奶牛连上边 (容量为1) 这个时候要拆点 因为每只奶牛只能才 ...

  7. POJ 3281 [网络流dinic算法模板]

    题意: 农场主有f种食物,d种饮料,n头牛. 接下来的n行每行第一个数代表第i头牛喜欢吃的食物数量,和第i头牛喜欢喝的饮料数目. 接下来分别是喜欢的食物和饮料的编号. 求解:农场主最多能保证几头牛同时 ...

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

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

  9. POJ 3281 Dining (网络流)

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

随机推荐

  1. SPRING代理模式

    1.静态代理 主题对象:Student public interface Student { public String add(); } 目标对象:RealStudent public class ...

  2. [转]使用 HTML5 WebSocket 构建实时 Web 应用

    HTML5 WebSocket 简介和实战演练 本文主要介绍了 HTML5 WebSocket 的原理以及它给实时 Web 开发带来的革命性的创新,并通过一个 WebSocket 服务器和客户端的案例 ...

  3. Java基础:(二)String字符串

    一.String概述 String被声明为final,因为它不可被继承. 内部使用char数组存储数据,该数组被声明为final,这意味着value数组初始化之后就不能再引用其他数组.并且String ...

  4. Spring的配置及jar包下载

    一.相关说明 IOC: Inversion of Control,控制反转,是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度.其中最常见的方式叫做依赖注入(Dependency In ...

  5. AngularJS(八):http服务

    本文也同步发表在我的公众号“我的天空” http服务 之前我们的示例都是在本地获取模拟数据,在实际应用中,所有的项目都将不可避免的从后台获取数据,我们都是通过Ajax来实现与服务器的通信.在Angul ...

  6. javascript对象的学习

    一.对象的定义: 对象是JavaScript的一个基本数据类型,是一种复合值,它将很多值(原始值或者其他对象)聚合在一起,可通过名字访问这些值.即属性的无序集合. JavaScript 提供多个内建对 ...

  7. 四道java语言练习基础题:

    一.==符的使 首先看一段比较有意思的代码 Integer a = 1000,b=1000; Integer c = 100,d=100; public void mRun(final String ...

  8. HoloLens | 世界的每一次变化,其实都提前打好了招呼

    新年,对灯发誓——不说老话,说新鲜事. 佛经上说:世间唯一永恒不变的,就是永远在变化. 130年前(说好的不说老话呢),世界上第一辆汽车在德国发出第一声轰鸣,世界变了: 现在,汽车已遍及世界,颜值.性 ...

  9. Countup.js:vue-countup-v2(npm)数字滚动插件

    1.官方地址:http://inorganik.github.io/countUp.js/ 2.官方demo: 3.参数说明: params——start(开始数字).end(结束数字).decima ...

  10. HDU 3681 Prison Break 越狱(状压DP,变形)

    题意: 给一个n*m的矩阵,每个格子中有一个大写字母,一个机器人从‘F’出发,拾取所有的开关‘Y’时便能够越狱,但是每走一格需要花费1点能量,部分格子为充电站‘G’,每个电站只能充1次电.而且部分格子 ...