poj 3281 && NYOJ 326 Dining 最大流问题 EK
来源:互联网 发布:淘宝售后率是什么意思 编辑:程序博客网 时间:2024/06/05 20:20
题目大意是N头牛,准备了F种食物,D种饮料,每一头牛会喜欢若干种食物和饮料,但它只能选择一种食物和一种饮料,且每种食物和饮料都只够一头牛选择,问怎样分配能使得食物和饮料都能得到的牛的数量最多,求这个数。
明显的一道最大流的题目,难点只在怎么建模。建模的方法如下:
1.建立一个超级源,跟每种食物之间连一条容量为1的边;
2.建立一个超级汇,它与每种饮料之间有一条容量为1的边;
3.将每头牛都拆分成两个点C1、C2,两点之间有一条容量为1的边;
4.若一头牛喜欢食物f,就将其对应的C1点与f连接起来,容量为1,若一头牛喜欢饮料d,同理将C2与d连接起来。
为何要拆点?
不拆点不能保证牛只能选择一种食物和一种饮料这一条件。即限定牛结点的容量为1。
至于最大流方面,数据规模不大就选了EK,当然这类题目还有变种,就要考虑其余的算法及优化手段了。
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#define inf 1000#define nMax 410#define Max(a,b) (a>b?a:b)#define Min(a,b) (a<b?a:b)int map[nMax][nMax];int N,F,D;int path[nMax];int queue[nMax * 100];int head,end;//bool flag[nMax];//广搜求一条增广路int bfs(){int minFlow = inf,u;memset(path, -1, sizeof(path));head = 0;end = 1;queue[head] = 0;while (head < end){u = queue[head ++];if (u == 2 * N + F + D + 1){break;}for (int i = 1; i <= 2 * N + F + D + 1; ++ i){if (path[i] == -1 && map[u][i] ){if (minFlow > map[u][i]){minFlow = map[u][i];}queue[end ++] = i;path[i] = u;}}}if (path[2 * N + F + D + 1] == -1){return -1;}return minFlow;}//EK算法,每次广搜得到一条增广路径,然后更新残留网络void Edmods_Karp(){int flow, maxFlow = 0, now, pre;while ((flow = bfs()) != -1){maxFlow += flow;now = 2 * N + F + D + 1;while (now != 0){pre = path[now];map[pre][now] -= flow;map[now][pre] += flow;now = pre;}}printf("%d\n", maxFlow);}//按照源点-食物-牛-牛-饮料-汇点的顺序建图void buildMap(){int fNum,dNum,fd;while (scanf("%d %d %d", &N, &F, &D) != EOF){memset(map, 0, sizeof(map));//memset(flag, false, sizeof(flag));for (int i = 1; i <= N; ++ i){scanf("%d %d", &fNum, &dNum);for (int j = 0; j < fNum; ++ j){scanf("%d", &fd);map[0][fd] = 1;map[fd][i + F] = 1;}map[i + F][i + F + N] = 1;for (int j = 0; j < dNum; ++ j){scanf("%d", &fd);map[fd + 2 * N + F][F + 2 * N + D + 1] = 1;map[i + F + N][fd + 2 * N + F] = 1;}}Edmods_Karp();}}//注意这里给点编号,0-源点,1-F是食物,F+1-F+N是牛左点,F+N+1-F+N+N是牛右点,F+N+N+1-F+N+N+D是drink饮料点,F+N+N+D+1是汇点int main(){buildMap();return 0;}
0 0
- poj 3281 && NYOJ 326 Dining 最大流问题 EK
- POJ 3281 Dining (网络流最大流 拆点建图 EK Dinic)
- POJ 3271:Dining(EK最大流)
- poj 3281 Dining 【图论-网络流-最大流-EK&Ford-Fulkerson】
- poj 3281 Dining 【最大流】
- poj 3281 Dining(最大流)
- POJ 3281 Dining(最大流)
- poj 3281 Dining 最大流
- poj 3281 Dining (最大流)
- poj 3281 Dining 【最大流】
- poj 3281 Dining (最大流)
- poj 3281 Dining 最大流
- POJ 3281 Dining 最大流
- poj 3281 Dining(最大流)
- poj 3281 Dining 最大流
- POJ-3281 Dining(最大流)
- POJ 3281 Dining(最大流)
- POJ-3281 Dining(最大流)
- 小小的知识点
- (1) quagga源码分析--大内总管zebra
- equals与==的区别
- log4j自定义级别并分类输出到文件
- 三相电机运转与相序的关系
- poj 3281 && NYOJ 326 Dining 最大流问题 EK
- Hibernate中query.setFirstResult() 和 query.setMaxResults用法
- 每日一题 No.33 字符串转数字函数的学习
- 1042. 字符统计(20)
- java script 面向对象
- 20170429-五一在家忙学习
- C++编程开发学习的50条建议
- Android 延时操作的三种方式
- (2) quagga源码分析--路由信息处理zebra-rib