题意:

有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. pytorch 安装错误,报 GLIBCXX_3.4.20 错误

    pytorch 从源码安装 链接:http://blog.csdn.net/u012442157/article/details/78134888 发现错误: 解决方案: http://blog.cs ...

  2. Java并发(一):基础概念

    对于Java并发,我也是属初学阶段,用的参考书是:"Java并发编程实战",写博时也参考了很多类似主题的博客,博主意在记录自己的学习路程,供网友讨论学习之用; 周末写的差不多了,今 ...

  3. [make error ]ubuntu显示不全

    make时候,输出到文件里 make >&makelog 就会自动出现一个makelog 会慢一些,不要急.

  4. freebsd问题

    http://community.spiceworks.com/topic/91708-server-freezes

  5. python之map,zip,reduce,filter的用法

    1.reduce(func,iterable,initial): 参数: - func 可执行函数 - iterable 可迭代对象 - initial 可选,初始参数 功能描述:调用func函数后, ...

  6. TC和脚本语言

    TC:Turbo C 集成开发环境是由Borland 公司开发的一套C 语言开发工具,它集成了程序编辑.调试.链接等多种功能.在DOS 系统时代,Turbo C 是被最广泛使用的一种PC 机应用程序开 ...

  7. win7下一直试用Beyond Compare 4

    找到目录C:\Users\用户名\AppData\Roaming\BeyondCompare,将这个目录删除,重启compare即可.

  8. ubuntu开放端口

    1.安装iptables(一般情况,ubuntu安装好的时候,iptables会被安装上),使用以下命令: $apt-get update $apt-get install iptables 2.安装 ...

  9. STM32F042开发板学习实践

    之前有粗略地学习过stm32F103的理论知识,但仅GPIO的配置.时钟配置就让人望而却步.现在手头有Nucleo STM32F042的开发板,而且ST已经推出STM32CubeMx图形化的工具软件, ...

  10. Factorialize a Number-freecodecamp算法题目

    Factorialize a Number(计算一个整数的阶乘) 要求 给定一个整数,求其阶乘(用字母n来代表一个整数,阶乘代表着所有小于或等于n的整数的乘积) 思路 确定乘的次数 用for循环进行累 ...