题目大意:有$n$头牛,$f$种食物和$d$种饮料,每种食物或饮料只能供一头牛享用,且每头牛只享用一种食物和一种饮料。每头牛都有自己喜欢的食物种类列表和饮料种类列表,问最多能使几头牛同时享用到自己喜欢的食物和饮料。

解题关键:设超级源点指向所有食物,饮料指向所有超级汇点,牛拆点为牛1和牛2,然后按照匹配进行建图,所有边权为1,保证每头牛不会贪吃,可知每条可行流为一个解,跑最大流即可。

一定注意坐标的范围分别代表什么,拆点的时候最容易出错的就是点坐标的表示。

牛拆点边权为1的原因是保证每头牛只能选1次。(相当于点的容量限制)

s->食物的边权为1的原因相当于把食物拆点

食物->牛边权为1的原因是食物和牛的匹配唯一

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #include<cstdlib>
  5. #include<cmath>
  6. #include<iostream>
  7. #include<queue>
  8. #include<vector>
  9. #define inf 0x3f3f3f3f
  10. #define MAX_V 500
  11. using namespace std;
  12. typedef long long ll;
  13. struct edge{int to,cap,rev;};
  14. vector<edge>G[MAX_V];
  15. int level[MAX_V],iter[MAX_V];
  16. void add_edge(int from,int to,int cap){
  17. G[from].push_back((edge){to,cap,(int)G[to].size()});
  18. G[to].push_back((edge){from,,(int)G[from].size()-});
  19. }
  20. void bfs(int s){
  21. memset(level,-,sizeof level);
  22. queue<int>que;
  23. level[s]=;
  24. que.push(s);
  25. while(!que.empty()){
  26. int v=que.front();que.pop();
  27. for(int i=;i<G[v].size();i++){
  28. edge &e=G[v][i];
  29. if(e.cap>&&level[e.to]<){
  30. level[e.to]=level[v]+;
  31. que.push(e.to);
  32. }
  33. }
  34. }
  35. }
  36.  
  37. int dfs(int v,int t,int f){
  38. if(v==t) return f;
  39. for(int &i=iter[v];i<G[v].size();i++){
  40. edge &e=G[v][i];
  41. if(e.cap>&&level[v]<level[e.to]){
  42. int d=dfs(e.to,t,min(f,e.cap));
  43. if(d>){
  44. e.cap-=d;
  45. G[e.to][e.rev].cap+=d;
  46. return d;
  47. }
  48. }
  49. }
  50. return ;
  51. }
  52.  
  53. int dinic(int s,int t){
  54. int flow=,f;
  55. while(){
  56. bfs(s);
  57. if(level[t]<) return flow;
  58. memset(iter,,sizeof iter);
  59. while((f=dfs(s,t,inf))>){
  60. flow+=f;
  61. }
  62. }
  63. return flow;
  64. }
  65. //拆点最重要的是如何分配坐标
  66. int n,f,d;
  67. int main(){
  68. while(scanf("%d%d%d",&n,&f,&d)!=EOF){
  69. memset(G,,sizeof G);
  70. for(int i=;i<=n;i++){
  71. int n1,n2,tmp;
  72. scanf("%d%d",&n1,&n2);
  73. for(int j=;j<=n1;j++){
  74. scanf("%d",&tmp);
  75. add_edge(*n+tmp,i,);
  76. }
  77. for(int j=;j<=n2;j++){
  78. scanf("%d",&tmp);
  79. add_edge(n+i,*n+f+tmp,);
  80. }
  81. }
  82. for(int i=;i<=n;i++) add_edge(i,n+i,);
  83. for(int i=;i<=f;i++) add_edge(,*n+i,);
  84. for(int i=;i<=d;i++) add_edge(*n+f+i,*n+f+d+,);
  85. printf("%d\n",dinic(,*n+f+d+));
  86. }
  87. return ;
  88. }

[poj3281]Dining(最大流+拆点)的更多相关文章

  1. POJ3281 Dining —— 最大流 + 拆点

    题目链接:https://vjudge.net/problem/POJ-3281 Dining Time Limit: 2000MS   Memory Limit: 65536K Total Subm ...

  2. POJ3281 Dining 最大流

    题意:有f种菜,d种饮品,每个牛有喜欢的一些菜和饮品,每种菜只能被选一次,饮品一样,问最多能使多少头牛享受自己喜欢的饮品和菜 分析:建边的时候,把牛拆成两个点,出和入 1,源点向每种菜流量为1 2,每 ...

  3. poj3281 Dining 最大流(奇妙的构图)

    我是按照图论500题的文档来刷题的,看了这题怎么也不觉得这是最大流的题目.这应该是题目做得太少的缘故. 什么是最大流问题?最大流有什么特点? 最大流的特点我觉得有一下几点: 1.只有一个起点.一个终点 ...

  4. POJ 3281 Dining(最大流+拆点)

    题目链接:http://poj.org/problem?id=3281 题目大意:农夫为他的 N (1 ≤ N ≤ 100) 牛准备了 F (1 ≤ F ≤ 100)种食物和 D (1 ≤ D ≤ 1 ...

  5. POJ3281:Dining(dinic+拆点)

    题目链接:http://poj.org/problem?id=3281 PS:刷够网络流了,先这样吧,之后再刷,慢慢补. 题意:有F种食物,D种饮料,N头奶牛,只能吃某种食物和饮料(而且只能吃特定的一 ...

  6. POJ3281 Dining(拆点构图 + 最大流)

    题目链接 题意:有F种食物,D种饮料N头奶牛,只能吃某种食物和饮料(而且只能吃特定的一份) 一种食物被一头牛吃了之后,其余牛就不能吃了第一行有N,F,D三个整数接着2-N+1行代表第i头牛,前面两个整 ...

  7. <每日一题>Day 9:POJ-3281.Dining(拆点 + 多源多汇+ 网络流 )

    Dining Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 24945   Accepted: 10985 Descript ...

  8. poj 3498 March of the Penguins(最大流+拆点)

    题目大意:在南极生活着一些企鹅,这些企鹅站在一些冰块上,现在要让这些企鹅都跳到同一个冰块上.但是企鹅有最大的跳跃距离,每只企鹅从冰块上跳走时会给冰块造成损害,因此企鹅跳离每个冰块都有次数限制.找出企鹅 ...

  9. poj 2391 Ombrophobic Bovines, 最大流, 拆点, 二分, dinic, isap

    poj 2391 Ombrophobic Bovines, 最大流, 拆点, 二分 dinic /* * Author: yew1eb * Created Time: 2014年10月31日 星期五 ...

随机推荐

  1. Swap file "/etc/.hosts.swp" already exists! [O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it,

    非正常关闭vi编辑器时会生成一个.swp文件 非正常关闭vi编辑器时会生成一个.swp文件 关于swp文件 使用vi,经常可以看到swp这个文件,那这个文件是怎么产生的呢,当你打开一个文件,vi就会生 ...

  2. Yii2数据库操作的各种写法

    -------------------------------ActiveRecord---------------------------------------- 查询: // find the ...

  3. Data Structure Trie: suffix problem

    http://www.geeksforgeeks.org/suffix-array-set-1-introduction/ http://www.geeksforgeeks.org/pattern-s ...

  4. 图解MFC基本框架(深入消息映射机制)

    首先,先看整体的消息流向图: 上图解释: 起点是消息循环,在winmain函数中(mfc中winmain函数是隐含的调用的,在app全局对象构造完后紧接着调用winmain函数),while循环中不断 ...

  5. Storm 执行异常 java.lang.RuntimeException: java.nio.channels.UnresolvedAddressException 问题解决

    最近写的 binlog2kafka storm job 上线在一个新的集群环境中(storm 0.9.0.1, kafka 0.8), storm job 运行时报出如下异常: java.lang.R ...

  6. Windows默认字符集_查询

    https://zhidao.baidu.com/question/32462047.html Windows95. XP……7操作系统自带的都是GBK字符集(含2万余汉字),是完全兼容GB2312( ...

  7. Python- 列表内置方法

    列表,元组 查 索引(下标) ,都是从0开始 切片 .count 查某个元素的出现次数 .index 根据内容找其对应的位置 "haidilao ge" in a 增加 a.app ...

  8. DbHelperSQL 事务写法!

    try { DBUtility.CommandInfo dbcom = new DBUtility.CommandInfo(); List<DBUtility.CommandInfo> s ...

  9. 在接口中的静态方法来获取model的实例对象

    直接先上代码: 接口代码 abstract class BaseModel { /** * @var null */ protected static $_instances = Array(); / ...

  10. uoj problem 14 DZY Loves Graph

    题目: DZY开始有 \(n\) 个点,现在他对这 \(n\) 个点进行了 \(m\) 次操作,对于第 \(i\) 个操作(从 \(1\) 开始编号)有可能的三种情况: Add a b: 表示在 \( ...