题意:

有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. 在docker上centos7 编译安装php7

    docker镜像来自daocloud.io/library/centos 首先下载libmcrypt库并make && make install yum -y install gcc ...

  2. SpringBoot 2.x (14):WebFlux响应式编程

    响应式编程生活案例: 传统形式: 一群人去餐厅吃饭,顾客1找服务员点餐,服务员把订单交给后台厨师,然后服务员等待, 当后台厨师做好饭,交给服务员,经过服务员再交给顾客1,依此类推,该服务员再招待顾客2 ...

  3. markdown-Macdown

    #标题 [页面锚点](#name)   =>   <a name="name"></a>文字 **加粗**(Command-B) *斜体*(Comma ...

  4. Elasticsearch-基本操作2

    Elasticsearch版本:6.0 为了避免并发修改的冲突问题,数据库中,经常用悲观锁和乐观锁来控制并发问题,而Elasticsearch使用乐观锁.如果源数据在读写过程中被修改,更新将失败,应用 ...

  5. PHP判断两个矩形是否相交

    <?php $s = is_rect_intersect(1,2,1,2,4,5,0,3); var_dump($s); /* 如果两个矩形相交,那么矩形A B的中心点和矩形的边长是有一定关系的 ...

  6. LeetCode:103Binary Tree Zigzag Level Order Traversal

    真是不容易啊,做这道题的时候脑子一团乱,感觉还是得劳逸结合啊.这道题的思想不难,就是宽搜BFS.通过设置一个flag来判断是否需要逆序输出. 我的做法虽然AC,但是觉得代码还是不好,空间占用较多. / ...

  7. mysql 忘记root密码的解决办法

    1.修改MySQL的登录设置: # vim /etc/my.cnf 在[mysqld]的段中加上一句:skip-grant-tables 例如: [mysqld] datadir=/var/lib/m ...

  8. less的使用总结

    简单执行less 一.使用npm全局安装less: npm install -g less 二.创建less文件 三.执行命令将less文件转换成css文件 lessc less/style.less ...

  9. 洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur

    屠龙宝刀点击就送 Tarjan缩点+拓扑排序 以后缩点后建图看n范围用vector ,或者直接用map+vector 结构体里数据要清空 代码: #include <cstring> #i ...

  10. C++11 function用法 可调用对象模板类

    std::function<datatype()> ()内写参数类型 datatype 代表function的返回值 灵活的用法.. 代码如下 #include <stdio.h&g ...