POJ 3281 Dining 最大流 Dinic算法
2015-06-14 23:36
302 查看
Dining
Description
Cows are such finicky eaters. Each cow has a preference for certain foods and drinks, and she will consume no others.
Farmer John has cooked fabulous meals for his cows, but he forgot to check his menu against their preferences. Although he might not be able to stuff everybody, he wants to give a complete meal of both food and drink to as many cows as possible.
Farmer John has cooked F (1 ≤ F ≤ 100) types of foods and prepared D (1 ≤ D ≤ 100) types of drinks. Each of his N (1 ≤ N ≤ 100) cows has decided whether she is willing to eat a particular food or drink a particular drink. Farmer John must assign a food type and a drink type to each cow to maximize the number of cows who get both.
Each dish or drink can only be consumed by one cow (i.e., once food type 2 is assigned to a cow, no other cow can be assigned food type 2).
Input
Line 1: Three space-separated integers: N, F, and D
Lines 2..N+1: Each line i starts with a two integers Fi and Di, the number of dishes that cow i likes and the number of drinks that cow i likes. The next Fi integers denote the dishes that cowi will eat, and the Di integers following that denote the drinks that cow i will drink.
Output
Line 1: A single integer that is the maximum number of cows that can be fed both food and drink that conform to their wishes
Sample Input
Sample Output
Hint
One way to satisfy three cows is:
Cow 1: no meal
Cow 2: Food #2, Drink #2
Cow 3: Food #1, Drink #1
Cow 4: Food #3, Drink #3
The pigeon-hole principle tells us we can do no better since there are only three kinds of food or drink. Other test data sets are more challenging, of course.
Source
USACO 2007 Open Gold
题意:农夫为他的牛准备了F种食物和D种饮料。每头牛都有各自喜欢的食物和饮料,而每种食物和饮料只能分配给一头牛。最多有多少头牛可以同时得到喜欢的食物和饮料?
我的第一道网络流的题目。
开始的思路:建立一个源点s和一个汇点t,然后把食物饮料和s,t建图,食物在前,饮料在后,然后把牛看成是流,跑一遍dinic,看有多少头牛可以到达t
这样的思路是错的:因为牛从s出发的时候不同的牛可以选择的路是不同的。
要怎么样才可以消除这种关系呢?
即怎么样才可以使得所有路径对所有流都是平等的,只有容量的限制。
再整理一下:
每头牛可以走的路径不一样
如果把牛,食物,饮料都看成是点,则每个点只可以经过一次。
所以建图:s,食物,牛,牛,饮料,t,正向容量都是1
s—食物的边,饮料—t的边的容量都是1,就保证了每种食物,饮料只被流经过一次
而牛—牛的边的容量为1,就保证了牛只被流经过一次
建图后,直接dinic即可。
值得说的是,这道题今晚8:30做到9:30左右AC了。
然后9:30的时候删掉,重新再打一次,结果第二次打错了,找bug找到现在才过,历时2hours。
原因:这个图是有向边,然后在addedge(from,to)的时候,我把部分边的起点和终点写反了。
这个一定要注意,下次不能再犯。
View Code
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 10768 | Accepted: 4938 |
Cows are such finicky eaters. Each cow has a preference for certain foods and drinks, and she will consume no others.
Farmer John has cooked fabulous meals for his cows, but he forgot to check his menu against their preferences. Although he might not be able to stuff everybody, he wants to give a complete meal of both food and drink to as many cows as possible.
Farmer John has cooked F (1 ≤ F ≤ 100) types of foods and prepared D (1 ≤ D ≤ 100) types of drinks. Each of his N (1 ≤ N ≤ 100) cows has decided whether she is willing to eat a particular food or drink a particular drink. Farmer John must assign a food type and a drink type to each cow to maximize the number of cows who get both.
Each dish or drink can only be consumed by one cow (i.e., once food type 2 is assigned to a cow, no other cow can be assigned food type 2).
Input
Line 1: Three space-separated integers: N, F, and D
Lines 2..N+1: Each line i starts with a two integers Fi and Di, the number of dishes that cow i likes and the number of drinks that cow i likes. The next Fi integers denote the dishes that cowi will eat, and the Di integers following that denote the drinks that cow i will drink.
Output
Line 1: A single integer that is the maximum number of cows that can be fed both food and drink that conform to their wishes
Sample Input
4 3 3 2 2 1 2 3 1 2 2 2 3 1 2 2 2 1 3 1 2 2 1 1 3 3
Sample Output
3
Hint
One way to satisfy three cows is:
Cow 1: no meal
Cow 2: Food #2, Drink #2
Cow 3: Food #1, Drink #1
Cow 4: Food #3, Drink #3
The pigeon-hole principle tells us we can do no better since there are only three kinds of food or drink. Other test data sets are more challenging, of course.
Source
USACO 2007 Open Gold
题意:农夫为他的牛准备了F种食物和D种饮料。每头牛都有各自喜欢的食物和饮料,而每种食物和饮料只能分配给一头牛。最多有多少头牛可以同时得到喜欢的食物和饮料?
我的第一道网络流的题目。
开始的思路:建立一个源点s和一个汇点t,然后把食物饮料和s,t建图,食物在前,饮料在后,然后把牛看成是流,跑一遍dinic,看有多少头牛可以到达t
这样的思路是错的:因为牛从s出发的时候不同的牛可以选择的路是不同的。
要怎么样才可以消除这种关系呢?
即怎么样才可以使得所有路径对所有流都是平等的,只有容量的限制。
再整理一下:
每头牛可以走的路径不一样
如果把牛,食物,饮料都看成是点,则每个点只可以经过一次。
所以建图:s,食物,牛,牛,饮料,t,正向容量都是1
s—食物的边,饮料—t的边的容量都是1,就保证了每种食物,饮料只被流经过一次
而牛—牛的边的容量为1,就保证了牛只被流经过一次
建图后,直接dinic即可。
值得说的是,这道题今晚8:30做到9:30左右AC了。
然后9:30的时候删掉,重新再打一次,结果第二次打错了,找bug找到现在才过,历时2hours。
原因:这个图是有向边,然后在addedge(from,to)的时候,我把部分边的起点和终点写反了。
这个一定要注意,下次不能再犯。
#include<cstring> #include<cstdio> #include<algorithm> #include<vector> #include<queue> using namespace std; const int maxn=405; const int inf=0x3f3f3f3f; struct Edge { int to,cap,rev; }; vector<Edge>edge[maxn]; int level[maxn]; int id[maxn]; int s=0; int t; void addedge(int from,int to) { edge[from].push_back((Edge){to,1,edge[to].size()}); edge[to].push_back((Edge){from,0,edge[from].size()-1}); } void bfs() { memset(level,-1,sizeof(level)); queue<int>que; while(!que.empty()) que.pop(); level[s]=0; que.push(s); while(!que.empty()) { int u=que.front(); que.pop(); for(int i=0;i<edge[u].size();i++) { Edge &e=edge[u][i]; if(e.cap>0&&level[e.to]<0) { level[e.to]=level[u]+1; que.push(e.to); } } } } int dfs(int u,int f) { if(u==t) return f; for(int &i=id[u];i<edge[u].size();i++) { Edge &e=edge[u][i]; if(e.cap>0&&level[e.to]>level[u]) { int d=dfs(e.to,min(e.cap,f)); if(d>0) { e.cap-=d; edge[e.to][e.rev].cap+=d; return d; } } } return 0; } int solve() { int res=0; while(true) { bfs(); if(level[t]<0) return res; memset(id,0,sizeof(id)); int flow; while(flow=dfs(s,inf)) { res+=flow; } } } int main() { int N,F,D; while(~scanf("%d%d%d",&N,&F,&D)) { for(int i=0;i<maxn;i++) edge[i].clear(); t=F+2*N+D+1; for(int i=1;i<=F;i++) addedge(s,i); for(int i=1;i<=D;i++) addedge(F+2*N+i,t); for(int i=1;i<=N;i++) addedge(i+F,i+F+N); for(int i=1;i<=N;i++) { int a,b; scanf("%d%d",&a,&b); for(int j=1;j<=a;j++) { int u; scanf("%d",&u); addedge(u,i+F); } for(int j=1;j<=b;j++) { int u; scanf("%d",&u); addedge(i+F+N,u+F+2*N); } } printf("%d\n",solve()); } return 0; }
View Code
相关文章推荐
- 团队作业-第四周-面向对象程序设计
- 关于“接口”的理解
- xxx cannot be resolved to a type 错误解决方法
- 第五节:使用反射发现类型成员
- spark入门讲座
- php换行符
- Java中的对象和对象引用
- 第一阶段冲刺总结
- matlab pca 函数 输入输出数据的意义
- 2015061409 - 怎么看公司给新员工的薪水高于老员工的薪水?
- 正则表达式
- DELET语句与REFERENCE约束“FK_news_category”冲突,该冲突发生于数据库“newssystem”,表dbo.news,column 'caId'语句终止
- <一> Linux是什么
- Linux添加 用户
- Functional MRI (second edition) -- 1. An introduction to fMRI
- NSArray中地内存管理 理解
- 、为什么要使用委托?
- Spring JdbcTemplate RowMapper vs ResultSetExtractor
- HDU 1134 卡特兰数 大数乘法除法
- 2015061408 - 规划一个人生?