Dining-最大流/Dinic
2014-04-22 21:49
232 查看
Dining
Source:POJ-3281
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 cow i 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
源代码:
代码分析:我是参考了别人的思路写出来的,个人觉得很精妙,牛化为两个子集,保证了只有一次选择的机会.很巧的.
Source:POJ-3281
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 cow i 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
源代码:
#include<iostream> #include<cstring> #include<queue> using namespace std; queue <int> Q; const int MAX = 600; const int INF = 1<<30; int C , F , D , Fi , Di , S , T; int mark[MAX] , level[MAX]; int map[MAX][MAX]; //C是牛的数目,F是食物的数目,D是饮料的数目,S是源点,T是汇点 //图为源点->食物->左牛->右牛->饮料->汇点 //两个牛集合保证了每头牛只能选择一批(一个食物和一瓶饮料)物品 int Dinic( void ); int bfs( void ); int dfs( int u , int flow ); int min( int a , int b ){ return a <= b ? a : b; } int main( ){ int i , j , k , ff , dd; while( cin>>C>>F>>D ){ S = 0 ; //源点为0 T = F + C + C + D + 1; //汇点为总点数+1 memset( map , 0 , sizeof( map ) ); //地图初始化 for( i=1 ; i<=F ; i++ ) map[S][i] = 1; //源点->食物 for( k=1 ; k<=C ; k++ ){ cin>>Fi>>Di; for( j=1 ; j<=Fi ; j++ ){ //食物->左牛集合 cin>>ff; map[ff][k+F] = 1; } map[k+F][k+F+C] = 1; //左牛集合->右牛集合 for( j=1 ; j<=Di ; j++ ){ cin>>dd; map[k+F+C][dd+F+C+C] = 1; //右牛集合->饮料 } } for( i=1 ; i<=D ; i++ ) map[i+F+2*C][T] = 1; //饮料->汇点 cout<<Dinic( ); } return 0; } int Dinic( void ){ int sum=0; while( bfs( ) ){ sum += dfs( S , INF ); } return sum; } int bfs( void ){ int u , v; memset( mark , 0 , sizeof( mark ) ); memset( level , 0 , sizeof( level ) ); while( !Q.empty() ) Q.pop( ); Q.push( S ); mark[S] = 1; while( !Q.empty() ){ u = Q.front( ); Q.pop( ); if( u==T ) return 1; for( v=S ; v<=T ; v++ ){ if( !mark[v] && map[u][v] ){ Q.push( v ); mark[v] = 1; level[v] = level[u] + 1; //层数加一 } } } return 0; } int dfs( int u , int flow ){ int v , flowSum , sum=0; if( u==T ) return flow; for( v=S ; v<=T ; v++ ){ if( level[v]==level[u]+1 && map[u][v] ){ flowSum = dfs( v , min( flow , map[u][v] ) ); map[u][v] -= flowSum; map[v][u] += flowSum; flow -= flowSum; //流量值减少 sum += flowSum; } } return sum; }
代码分析:我是参考了别人的思路写出来的,个人觉得很精妙,牛化为两个子集,保证了只有一次选择的机会.很巧的.
相关文章推荐
- linux线程间通信之信号量
- iOS NSNotification的使用
- 【游戏】对等轴测投影 Isometric Projection
- Java4Android(第36~39集)线程 及 同步
- int型转字符串型函数itoa()实现
- C#迷宫的实现(1)
- hadoop example
- 学习mfc书籍
- JAVA -- HttpServletResponse 的状态码含义及方法说明
- HDU 1695 GCD
- Bytebuffer 和DirectByteBuffer
- HDU 2110 Crisis of HDU (母函数问题)
- Java学习笔记-策略模式
- 计算机网络面试题
- 对linux档案系统以及磁盘管理的一点总结(一)
- 教你如何从wireshark中的RTSP流媒体提取H.264码流数据
- Optimal Milking-最大流/FordFulkerson/Dinic
- template undefined reference——gcc
- 【js】将table的每个td的内容自动赋值给其title属性
- c++-类与结构体