USACO 奶牛食品(网络流)
2015-08-04 21:48
295 查看
题目大意:
FJ的奶牛们只吃各自喜欢的一些特定的食物和饮料,除此之外的其他食物和饮料一概不吃。某天FJ为奶牛们精心准备了一顿美妙的饭食,但在之前忘记检查奶牛们的菜单,这样显然是不能不能满足所有奶牛的要求。但是FJ又不愿意为此重新来做,所以他他还是想让尽可能多的牛吃到他们喜欢的食品和饮料。
FJ提供了F (编号为1、2、…、F)种食品并准备了D (编号为1、2、…、D)种饮料, 他的N头牛(编号为1、2、…、N)都已决定了是否愿意吃某种食物和喝某种饮料。FJ想给每一头牛一种食品和一种饮料,使得尽可能多的牛得到喜欢的食物和饮料。
每一种食物和饮料只能由一头牛来用。例如如果食物2被一头牛吃掉了,没有别的牛能吃到食物2。
(原谅我找不到原题,只有把学校OJ的题粘过来)
思路:网络流的模板题,f作为左边一部,把每头奶牛拆点,同一头奶牛之间连一条边权值为1的边,代表这头奶牛只能用一次,如果不拆点,那么同一头奶牛就可能同时满足两种饮料和两种食物,不符合题意(之前没有拆点,结果在学校OJ的破数据下居然过了QAQ);d作为右边一部,起点向f部连边,d部向终点连边。
FJ的奶牛们只吃各自喜欢的一些特定的食物和饮料,除此之外的其他食物和饮料一概不吃。某天FJ为奶牛们精心准备了一顿美妙的饭食,但在之前忘记检查奶牛们的菜单,这样显然是不能不能满足所有奶牛的要求。但是FJ又不愿意为此重新来做,所以他他还是想让尽可能多的牛吃到他们喜欢的食品和饮料。
FJ提供了F (编号为1、2、…、F)种食品并准备了D (编号为1、2、…、D)种饮料, 他的N头牛(编号为1、2、…、N)都已决定了是否愿意吃某种食物和喝某种饮料。FJ想给每一头牛一种食品和一种饮料,使得尽可能多的牛得到喜欢的食物和饮料。
每一种食物和饮料只能由一头牛来用。例如如果食物2被一头牛吃掉了,没有别的牛能吃到食物2。
(原谅我找不到原题,只有把学校OJ的题粘过来)
思路:网络流的模板题,f作为左边一部,把每头奶牛拆点,同一头奶牛之间连一条边权值为1的边,代表这头奶牛只能用一次,如果不拆点,那么同一头奶牛就可能同时满足两种饮料和两种食物,不符合题意(之前没有拆点,结果在学校OJ的破数据下居然过了QAQ);d作为右边一部,起点向f部连边,d部向终点连边。
#include<cstdio> #define MAXN 510 #define Min(a,b) a<b?a:b #define INF 999999999 #define BIG 123456789 using namespace std; int c[MAXN][MAXN]; int dd[MAXN]; int vd[MAXN]; int s,t,n,f,d,flow; int aug(int u,int augco) { int j,augc = augco,mind = t-1,delta; if(u == t) return augco; for(j = 0; j <= t; j++) if(c[u][j]) { if(dd[u] == dd[j]+1) { delta = Min(c[u][j],augc); delta = aug(j,delta); c[u][j] -= delta; c[j][u] += delta; augc -= delta; if(dd[s] > t) return augco - augc; if(augc == 0) break; } mind = Min(mind,dd[j]); } if(augco == augc) { vd[dd[u]]--; if(vd[dd[u]] == 0) dd[s] = t; dd[u] = mind+1; vd[dd[u]]++; } return augco - augc; } void sap() { vd[0] = t; while(dd[1] < t) flow += aug(1,BIG); } int main() { int p1,p2,v; scanf("%d%d%d",&n,&f,&d); t = n*2+f+d+2; for(int i = 1; i <= n; i++) c[f+1+2*(i-1)+1][f+1+i*2] = 1; for(int i = 1; i <= f; i++) c[1][i+1] = 1; for(int i = 1; i <= d; i++) c[f+1+2*n+i][t] = 1; for(int i = 1; i <= n; i++) { scanf("%d%d",&p1,&p2); for(int j = 1; j <= p1; j++) { scanf("%d",&v); c[v+1][f+1+2*(i-1)+1] = 1; } for(int j = 1; j <= p2; j++) { scanf("%d",&v); c[f+1+2*i][v+f+1+2*n] = 1; } } sap(); printf("%d\n",flow); }
相关文章推荐
- JAVA网络编程之——URL类
- 转:HTTP长连接和短连接原理浅析
- C#网络编程《二》
- 理解SSL(https)中的对称加密与非对称加密
- Virtualbox之Ubuntu虚拟机网络访问设置
- 8月2日----TCP Socket 编程
- Windows Socket网络编程——第二章 Windows Socket概念
- Redis高可用开源缓存集群方案--总结自网络
- java基础第九讲——反射、工厂设计模式、注解、线程、网络与线程的结合
- 将HttpServletRequest中的参数反射至实体类
- TCP协议中的三次握手和四次挥手(图解)&&TCP/IP 七层网络模型
- ACM hdu5352 最小费用最大流 模板 网络流
- 计算机网络面试题2
- 【linux高级程序设计】(第十四章)TCP高级应用 3
- HTTP请求在网络中的详细过程
- Python socket模拟HTTP请求
- Android中加载网络图片到本地
- TCP三次握手及其背后的缺陷
- TCP三次握手及其背后的缺陷
- 边框圆角化方式(原文链接http://www.cnblogs.com/SJP666/p/4678730.html)