poj 3281 Dining (最大网络流)
题目链接:
http://poj.org/problem?id=3281
题目大意:
有n头牛,f种食物,d种饮料,第i头牛喜欢fi种食物和di种饮料,每种食物或者饮料被一头牛选中后,就不能被其他的牛选了,问最多能满足多少头牛的要求?
解题思路:
最大匹配问题,关键在于如何建图,可以虚构出来一个源点,一个汇点,一共需要f+d+2*n+2个点即可,建图为:源点—>食物—>牛—>牛—>饮料—> 汇点。把牛作为点拆开建图是为了让一头牛只对应一种饮料和一种食物,避免出现对应多种饮料或者多种食物的情况。
代码:
- #include <cstdio>
- #include <cstring>
- #include <cstdlib>
- #include <algorithm>
- #include <iostream>
- #include <cmath>
- #include <queue>
- using namespace std;
- #define maxn 0x3f3f3f3f
- #define N 410
- int map[N][N], Layer[N], s, e;
- bool visit[N];
- bool CountLayer();
- int Dinic ();
- int main ()
- {
- int n, f, d, x, y, m;
- while (scanf ("%d %d %d", &n, &f, &d) != EOF)
- {
- s = , e = f + d + n + n + ;
- memset (map, , sizeof(map));
- for (int i=; i<=f; i++)
- map[][i] = ;//食物和源点连线
- for (int i=; i<=d; i++)
- map[i+f+*n][e] = ;//饮料和汇点链接
- for (int i=; i<=n; i++)
- map[i+f][i+f+n] = ;//对应的牛和牛链接
- for (int i=; i<=n; i++)
- {//建立牛和食物及饮料的关系
- int num = f + i;
- scanf ("%d %d", &x, &y);
- while (x --)
- {
- scanf ("%d", &m);
- map[m][num] = ;
- }
- while (y --)
- {
- scanf ("%d", &m);
- map[num + n][m+f+*n] = ;
- }
- }
- printf ("%d\n", Dinic());
- }
- return ;
- }
- bool CountLayer()
- {
- deque <int> Q;
- memset (Layer, , sizeof(Layer));
- Layer[] = ;
- Q.push_back();
- while (!Q.empty())
- {
- int nd = Q.front();
- Q.pop_front();
- for (int i=s; i<=e; i++)
- {
- if (map[nd][i]> && !Layer[i])
- {
- Layer[i] = Layer[nd] + ;
- if (i == e)
- return true;
- else
- Q.push_back(i);
- }
- }
- }
- return false;
- }
- int Dinic ()//Dinic模板
- {
- int maxnflow = , i;
- while (CountLayer())
- {
- deque<int>Q;
- memset (visit, , sizeof(visit));
- visit[] = ;
- Q.push_back();
- while (!Q.empty())
- {
- int nd = Q.back();
- if (nd != e)
- {
- for (i=; i<=e; i++)
- {
- if (map[nd][i]> && Layer[i] == Layer[nd]+ && !visit[i])
- {
- visit[i] = ;
- Q.push_back(i);
- break;
- }
- }
- if (i > e)
- Q.pop_back();
- }
- else
- {
- int minflow = maxn;
- int mv;
- for (i=; i<Q.size(); i++)
- {
- int ns = Q[i-];
- int ne = Q[i];
- if (map[ns][ne] < minflow)
- {
- minflow = map[ns][ne];
- mv = ns;
- }
- }
- maxnflow += minflow;
- for (i=; i<Q.size(); i++)
- {
- int ns = Q[i-];
- int ne = Q[i];
- map[ns][ne] -= minflow;
- map[ne][ns] += minflow;
- }
- while (!Q.empty() && Q.back() != mv)
- Q.pop_back();
- }
- }
- }
- return maxnflow;
- }
poj 3281 Dining (最大网络流)的更多相关文章
- POJ 3281 Dining (网络流)
POJ 3281 Dining (网络流) Description Cows are such finicky eaters. Each cow has a preference for certai ...
- POJ 3281 Dining(网络流拆点)
[题目链接] http://poj.org/problem?id=3281 [题目大意] 给出一些食物,一些饮料,每头牛只喜欢一些种类的食物和饮料, 但是每头牛最多只能得到一种饮料和食物,问可以最多满 ...
- poj 3281 Dining(网络流+拆点)
Dining Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 20052 Accepted: 8915 Descripti ...
- POJ 3281 Dining(网络流最大匹配)
分析: 数学模型是三个集合A,B,C,(a,b,c)构成一个匹配.因为图一个点只能匹配一次,把a拆点a',a", 在可以匹配的点上连边,s - b - a' - a" - c - ...
- POJ 3281 Dining(最大流)
POJ 3281 Dining id=3281" target="_blank" style="">题目链接 题意:n个牛.每一个牛有一些喜欢的 ...
- poj 3281 Dining 网络流-最大流-建图的题
题意很简单:JOHN是一个农场主养了一些奶牛,神奇的是这些个奶牛有不同的品味,只喜欢吃某些食物,喝某些饮料,傻傻的John做了很多食物和饮料,但她不知道可以最多喂饱多少牛,(喂饱当然是有吃有喝才会饱) ...
- POJ 3281 Dining 网络流最大流
B - DiningTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/view.ac ...
- poj 3281 Dining【拆点网络流】
Dining Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 11828 Accepted: 5437 Descripti ...
- POJ 3281 Dining (网络流之最大流)
题意:农夫为他的 N (1 ≤ N ≤ 100) 牛准备了 F (1 ≤ F ≤ 100)种食物和 D (1 ≤ D ≤ 100) 种饮料.每头牛都有各自喜欢的食物和饮料, 而每种食物或饮料只能分配给 ...
随机推荐
- Nexus3.0.1如何上传第三方插件
原文:http://blog.csdn.net/wang465745776/article/details/52527905 前提条件 Nexus 3.0.1 提出问题 如何上传第三方插件到Nexus ...
- mysql中如何查询最近24小时、top n查询
MySQL中如何查询最近24小时. where visittime >= NOW() - interval 1 hour; 昨天. where visittime between CURDATE ...
- CentOS 6.x Radius
CentOS 6.x Radius 一. 实现环境: 1.系统:CentOS release 6.6 (Final) 2.需要软件包: 1) freeradius-2.1.12-6.e16.x ...
- Office WORD如何取消开始工作右侧栏
工具-选项-视图,取消勾选"启动任务窗格"
- java克隆对象clone()的使用方法和作用
转自:997.html">http://www.okrs.cn/blog/news/?997.html 内容摘要 若需改动一个对象,同一时候不想改变调用者的对象.就要制作该对象的一个本 ...
- HDU1542Atlantis(扫描线)
HDU1542Atlantis(扫描线) 题目链接 题目大意:给你n个覆盖矩形,问最后覆盖的面积. 解题思路:将每一个矩形拆成两条线段,一条是+1的,还有一条是减1的.然后扫描先从上往下扫描,碰到加1 ...
- 【网站支付PHP篇】thinkPHP集成支付宝支付(担保交易)
目录 系列说明 开发环境 部署支付宝 支付请求 支付宝返回处理 系列说明 最近在帮朋友的系统安装支付模块(兑换网站积分),现在总结一些开发心得,希望对大家有用.这个系列会讲以下第三方支付平台的集成: ...
- VS2010打开高版本VS解决方案
http://blog.csdn.net/backspace110/article/details/62111273 Microsoft Visual Studio Solution File, Fo ...
- ubuntu中查看已安装软件包的方法
ubuntu中查看已安装软件包的方法: 方法一:在新立得软件包管理器中,打到已安装,便可以看看有多少包被安装. 如果想把这些包的信息复制到一文件里,可用下面的方法. 方法二:在终端输入 sudo dp ...
- C中使用memset
int i; cout<<memset(&i,1,sizeof(int))<<endl; 输出结果是16843009,而不是填充的1111 1111,为什么呢? 因为m ...