题意:

有F种食物和D种饮料,每头牛有各自喜欢的食物和饮料,而且每种食物或者饮料只能给一头牛。

求最多能有多少头牛能同时得到它喜欢的食物或者饮料。

分析:

把每个牛拆点,中间连一条容量为1的边,保证一头牛不会被多个食物或者饮料分配。

然后把饮料和牛连边,食物和另外一边的牛连边,最后增加一个源点和汇点跑最大流。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <vector>
  6. #include <queue>
  7. using namespace std;
  8.  
  9. const int maxn = + ;
  10. const int maxnode = + ;
  11. const int INF = 0x3f3f3f3f;
  12.  
  13. int N, F, D;
  14.  
  15. int n, s, t;
  16.  
  17. struct Edge
  18. {
  19. int from, to, cap, flow;
  20. Edge(int u, int v, int c, int f):from(u), to(v), cap(c), flow(f) {}
  21. };
  22.  
  23. vector<Edge> edges;
  24. vector<int> G[maxnode];
  25.  
  26. void init()
  27. {
  28. edges.clear();
  29. for(int i = ; i < n; i++) G[i].clear();
  30. }
  31.  
  32. void AddEdge(int u, int v, int c)
  33. {
  34. edges.push_back(Edge(u, v, c, ));
  35. edges.push_back(Edge(v, u, , ));
  36. int m = edges.size();
  37. G[u].push_back(m - );
  38. G[v].push_back(m - );
  39. }
  40.  
  41. bool vis[maxnode];
  42. int d[maxnode];
  43. int cur[maxnode];
  44.  
  45. bool BFS()
  46. {
  47. d[s] = ;
  48. queue<int> Q;
  49. Q.push(s);
  50. memset(vis, false, sizeof(vis));
  51. vis[s] = true;
  52.  
  53. while(!Q.empty())
  54. {
  55. int u = Q.front(); Q.pop();
  56. for(int i = ; i < G[u].size(); i++)
  57. {
  58. Edge& e = edges[G[u][i]];
  59. int v = e.to;
  60. if(!vis[v] && e.cap > e.flow)
  61. {
  62. vis[v] = true;
  63. d[v] = d[u] + ;
  64. Q.push(v);
  65. }
  66. }
  67. }
  68.  
  69. return vis[t];
  70. }
  71.  
  72. int DFS(int u, int a)
  73. {
  74. if(u == t || a == ) return a;
  75. int flow = , f;
  76. for(int& i = cur[u]; i < G[u].size(); i++)
  77. {
  78. Edge& e = edges[G[u][i]];
  79. int v = e.to;
  80. if(d[v] == d[u] + && (f = DFS(v, min(a, e.cap - e.flow))) > )
  81. {
  82. flow += f;
  83. e.flow += f;
  84. a -= f;
  85. edges[G[u][i]^].flow -= f;
  86. if(a == ) break;
  87. }
  88. }
  89. return flow;
  90. }
  91.  
  92. int Maxflow()
  93. {
  94. int flow = ;
  95. while(BFS())
  96. {
  97. memset(cur, , sizeof(cur));
  98. flow += DFS(s, INF);
  99. }
  100. return flow;
  101. }
  102.  
  103. int main()
  104. {
  105. while(scanf("%d%d%d", &N, &F, &D) == )
  106. {
  107. n = N * + D + F + ;
  108. s = , t = n - ;
  109. init();
  110.  
  111. //build graph
  112. for(int i = ; i <= F; i++) AddEdge(s, N*+i, );
  113. for(int i = ; i <= D; i++) AddEdge(N*+F+i, t, );
  114. for(int i = ; i <= N; i++) AddEdge(i, i + N, );
  115.  
  116. for(int i = ; i <= N; i++)
  117. {
  118. int f, d, x; scanf("%d%d", &f, &d);
  119. while(f--)
  120. {
  121. scanf("%d", &x);
  122. AddEdge(N*+x, i, );
  123. }
  124. while(d--)
  125. {
  126. scanf("%d", &x);
  127. AddEdge(N + i, N*+F+x, );
  128. }
  129. }
  130.  
  131. printf("%d\n", Maxflow());
  132. }
  133.  
  134. return ;
  135. }

代码君

POJ 3281 网络流 拆点 Dining的更多相关文章

  1. POJ 3281 网络流 拆点保证本身只匹配一对食物和饮料

    如何建图? 最开始的问题就是,怎么表示一只牛有了食物和饮料呢? 后来发现可以先将食物与牛匹配,牛再去和饮料匹配,实际上这就构成了三个层次. 起点到食物层边的容量是1,食物层到奶牛层容量是1,奶牛层到饮 ...

  2. poj 3281(网络流+拆点)

    题目链接:http://poj.org/problem?id=3281 思路:设一个超级源点和一个超级汇点,源点与食物相连,饮料与汇点相连,然后就是对牛进行拆点,一边喜欢的食物相连,一边与喜欢的饮料相 ...

  3. POJ 3281 网络流dinic算法

    B - Dining Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit S ...

  4. B - Dining POJ - 3281 网络流

    Cows are such finicky eaters. Each cow has a preference for certain foods and drinks, and she will c ...

  5. ACM Computer Factory POJ - 3436 网络流拆点+路径还原

    http://poj.org/problem?id=3436 每台电脑有$p$个组成部分,有$n$个工厂加工电脑. 每个工厂对于进入工厂的半成品的每个组成部分都有要求,由$p$个数字描述,0代表这个部 ...

  6. POJ 3281 网络流

    题意: 思路: 网络流 重在建图- 建完了图 就一切都好说了 这道题 我的想法是 先把源点和所有的食品连上边 (容量为1) 再把食品和对应的奶牛连上边 (容量为1) 这个时候要拆点 因为每只奶牛只能才 ...

  7. POJ 3281 [网络流dinic算法模板]

    题意: 农场主有f种食物,d种饮料,n头牛. 接下来的n行每行第一个数代表第i头牛喜欢吃的食物数量,和第i头牛喜欢喝的饮料数目. 接下来分别是喜欢的食物和饮料的编号. 求解:农场主最多能保证几头牛同时 ...

  8. poj 3281 Dining 网络流-最大流-建图的题

    题意很简单:JOHN是一个农场主养了一些奶牛,神奇的是这些个奶牛有不同的品味,只喜欢吃某些食物,喝某些饮料,傻傻的John做了很多食物和饮料,但她不知道可以最多喂饱多少牛,(喂饱当然是有吃有喝才会饱) ...

  9. POJ 3281 Dining (网络流)

    POJ 3281 Dining (网络流) Description Cows are such finicky eaters. Each cow has a preference for certai ...

随机推荐

  1. restful之http讲解

    HTTP(HyperText Transfer Protocol)是一套计算机通过网络进行通信的规则.计算机专家设计出HTTP,使HTTP客户(如Web浏览器)能够从HTTP服务器(Web服务器)请求 ...

  2. [选择排序] 时间复杂度O(n^2)

    思路:从未排序的序列中,找到最小的元素,放到序列的起始位置, 再从剩下没排序的里面,找到最小的,放到已经排序的末尾. 原地操作几乎是选择排序的唯一优点,当空间复杂度要求较高时,可以考虑选择排序:实际适 ...

  3. freebsd快速删除磁盘数据

    At the start, mark all system disks as empty. Repeat the following command for each hard drive: dd i ...

  4. 使用poi或jxl,通过java读写xls、xlsx文档

    package nicetime.com.baseutil; import jxl.Sheet;import jxl.Workbook;import jxl.read.biff.BiffExcepti ...

  5. web端 repeat和简单控件

    <%@ %> - 这里面写一些声明和引用的<% %> - 编写C#代码的<%= %><%# %> Repeater - 重复器     相当于winfo ...

  6. 卓越管理的实践技巧(3)推动团队管理的要点 Facilitation Essentials for Managers

    Facilitation Essentials for Managers 前文卓越管理的秘密(Behind Closed Doors)最后一部分提到了总结的13条卓越管理的实践技巧并列出了所有实践技巧 ...

  7. jquery绑定事件的系统参数传递方法

    如果是传递的事件自带函数,,可使用以下语法(以鼠标移动事件为例): init: function () { $(document).on("mousemove",loginOper ...

  8. groups - 显示用户所在的组

    总览 (SYNOPSIS) groups [OPTION]... [USERNAME]... 描述 (DESCRIPTION) --help 显示此帮助, 然后退出 --version 显示版本信息, ...

  9. tomcat - CPU高占用问题记录

    先查询进程 top 再根据进程号,查出进程的线程 ps p 3036 -L -o pcpu,pid,tid,time,tname,cmd 得到最高使用率CPU的线程TID,转换成16进制 printf ...

  10. PhoneGap+JQuery Mobile移动应用开发学习笔记

    最近一直在学习使用PhoneGap+JQuery Mobile的开发框架开发Android应用,抛开这个框架的运行效率不说,暂且将使用中遇到的问题进行一下整理. 1.JS文件引用顺序 也许在进行web ...