题目大意:

有k个挤奶器,在牧场里有c头奶牛,每个挤奶器可以满足m个奶牛,奶牛和挤奶器都可以看成是实体,现在给出两个实体之间的距离,如果没有路径相连,则为0,现在问你在所有方案里面,这c头奶牛需要走的最大距离的最小值。

分析:

先将题目给出来的距离矩阵跑一下 Floyd 求出全源最短路方便后面建图,

这里注意一下除了对角线的点若有其他点为 0 则应将其值设置为 INF 代表不可达

在使用最大流判断是否存在解的时候,要对每个解都重新建图。

建图需要一个超级源点,把所有的奶牛与源点相连,容量设置为1

把所有的挤奶器与汇点相连,容量为m

然后对于挤奶器和奶牛的距离不超过判断的解的距离的连边,容量设置为1

然后求解即可。如果最大流 == 牛的总数说明可行

AC代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int maxn = ;
  4. const int INF = 0x3f3f3f3f;
  5. int mp[maxn][maxn];
  6. int L,R;
  7. struct Edge
  8. {
  9. int from,to,cap,flow;
  10. Edge(){}
  11. Edge(int from,int to,int cap,int flow):from(from),to(to),cap(cap),flow(flow){}
  12.  
  13. };
  14.  
  15. struct Dinic
  16. {
  17. int n,m,s,t; //结点数,边数(包括反向弧),源点与汇点编号
  18. vector<Edge> edges; //边表 edges[e]和edges[e^1]互为反向弧
  19. vector<int> G[maxn]; //邻接表,G[i][j]表示结点i的第j条边在e数组中的序号
  20. bool vis[maxn]; //BFS使用,标记一个节点是否被遍历过
  21. int d[maxn]; //d[i]表从起点s到i点的距离(层次)
  22. int cur[maxn]; //cur[i]表当前正访问i节点的第cur[i]条弧
  23.  
  24. void init(int n,int s,int t)
  25. {
  26. this->n=n,this->s=s,this->t=t;
  27. for(int i=;i<=n;i++) G[i].clear();
  28. edges.clear();
  29. }
  30.  
  31. void AddEdge(int from,int to,int cap)
  32. {
  33. edges.push_back( Edge(from,to,cap,) );
  34. edges.push_back( Edge(to,from,,) );
  35. m = edges.size();
  36. G[from].push_back(m-);
  37. G[to].push_back(m-);
  38. }
  39.  
  40. bool BFS()
  41. {
  42. memset(vis,,sizeof(vis));
  43. queue<int> Q;//用来保存节点编号的
  44. Q.push(s);
  45. d[s]=;
  46. vis[s]=true;
  47. while(!Q.empty())
  48. {
  49. int x=Q.front(); Q.pop();
  50. for(int i=; i<G[x].size(); i++)
  51. {
  52. Edge& e=edges[G[x][i]];
  53. if(!vis[e.to] && e.cap>e.flow)
  54. {
  55. vis[e.to]=true;
  56. d[e.to] = d[x]+;
  57. Q.push(e.to);
  58. }
  59. }
  60. }
  61. return vis[t];
  62. }
  63.  
  64. //a表示从s到x目前为止所有弧的最小残量
  65. //flow表示从x到t的最小残量
  66. int DFS(int x,int a)
  67. {
  68. //printf("%d %d\n", x, a);
  69. if(x==t || a==)return a;
  70. int flow=,f;//flow用来记录从x到t的最小残量
  71. for(int& i=cur[x]; i<G[x].size(); i++)
  72. {
  73. Edge& e=edges[G[x][i]];
  74. if(d[x]+==d[e.to] && (f=DFS( e.to,min(a,e.cap-e.flow) ) )> )
  75. {
  76. e.flow +=f;
  77. edges[G[x][i]^].flow -=f;
  78. flow += f;
  79. a -= f;
  80. if(a==) break;
  81. }
  82. }
  83. return flow;
  84. }
  85.  
  86. int Maxflow()
  87. {
  88. int flow=;
  89. while(BFS())
  90. {
  91. memset(cur,,sizeof(cur));
  92. flow += DFS(s,INF);
  93. }
  94. return flow;
  95. }
  96. }DC;
  97. void FD(int K,int C)
  98. {
  99. int n=K+C;
  100. L=INF,R=-INF;
  101. for(int k= ; k<=n ; k++)
  102. {
  103. for(int i= ; i<=n ; i++)
  104. {
  105. for(int j= ; j<=n ; j++)
  106. {
  107. mp[i][j]=min(mp[i][k]+mp[k][j],mp[i][j]);
  108. L=min(L,mp[i][j]);
  109. R=max(R,mp[i][j]);
  110. }
  111.  
  112. }
  113. }
  114. }
  115. bool ok(int mid,int k,int c,int m)
  116. {
  117. int n=k+c+;
  118. DC.init(n+,,n);
  119. for(int i= ; i<=c ; i++)
  120. DC.AddEdge(,k+i,);
  121. for(int i= ; i<=k ; i++)
  122. DC.AddEdge(i,n,m);
  123. for(int i=k+ ; i<=k+c ; i++)
  124. for(int j= ; j<=k ; j++)
  125. if(mp[i][j]<=mid)
  126. DC.AddEdge(i,j,INF);
  127. return (DC.Maxflow()==c);
  128. }
  129.  
  130. int main( )
  131. {
  132. int k,c,m;
  133. while(scanf("%d%d%d",&k,&c,&m)!=EOF)
  134. {
  135. for(int i= ; i<=k+c ; i++)
  136. for(int j= ; j<=k+c ; j++)
  137. {
  138. scanf("%d",&mp[i][j]);
  139. if(i!=j&&mp[i][j]==)
  140. mp[i][j]=INF;
  141. }
  142. FD(k,c);
  143. int ans;
  144. while(L<=R)
  145. {
  146. int mid = (L+R)>>;
  147. if(!ok(mid,k,c,m))
  148. L = mid+;
  149. else
  150. {
  151. ans=mid;
  152. R=mid-;
  153. }
  154. }
  155. printf("%d\n",ans);
  156. }
  157. return ;
  158. }

POJ-2112 Optimal Milking(floyd+最大流+二分)的更多相关文章

  1. Poj 2112 Optimal Milking (多重匹配+传递闭包+二分)

    题目链接: Poj 2112 Optimal Milking 题目描述: 有k个挤奶机,c头牛,每台挤奶机每天最多可以给m头奶牛挤奶.挤奶机编号从1到k,奶牛编号从k+1到k+c,给出(k+c)*(k ...

  2. POJ 2112.Optimal Milking (最大流)

    时间限制:2s 空间限制:30M 题意: 有K台挤奶机(编号1~K),C头奶牛(编号K+1~K+C),给出各点之间距离.现在要让C头奶牛到挤奶机去挤奶,每台挤奶机只能处理M头奶牛,求使所走路程最远的奶 ...

  3. POJ 2112 Optimal Milking ( 经典最大流 && Floyd && 二分 )

    题意 : 有 K 台挤奶机器,每台机器可以接受 M 头牛进行挤奶作业,总共有 C 头奶牛,机器编号为 1~K,奶牛编号为 K+1 ~ K+C ,然后给出奶牛和机器之间的距离矩阵,要求求出使得每头牛都能 ...

  4. POJ 2112 Optimal Milking (Floyd+二分+最大流)

    [题意]有K台挤奶机,C头奶牛,在奶牛和机器间有一组长度不同的路,每台机器每天最多能为M头奶牛挤奶.现在要寻找一个方案,安排每头奶牛到某台机器挤奶,使得C头奶牛中走过的路径长度的和的最大值最小. 挺好 ...

  5. POJ 2112 Optimal Milking(最大流)

    题目链接:http://poj.org/problem?id=2112 Description FJ has moved his K (1 <= K <= 30) milking mach ...

  6. POJ 2112 Optimal Milking (二分 + floyd + 网络流)

    POJ 2112 Optimal Milking 链接:http://poj.org/problem?id=2112 题意:农场主John 将他的K(1≤K≤30)个挤奶器运到牧场,在那里有C(1≤C ...

  7. POJ 2112 Optimal Milking (二分+最短路径+网络流)

    POJ  2112 Optimal Milking (二分+最短路径+网络流) Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K To ...

  8. POJ 2112—— Optimal Milking——————【多重匹配、二分枚举答案、floyd预处理】

    Optimal Milking Time Limit:2000MS     Memory Limit:30000KB     64bit IO Format:%I64d & %I64u Sub ...

  9. POJ 2112 Optimal Milking (Dinic + Floyd + 二分)

    Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 19456   Accepted: 6947 ...

随机推荐

  1. 关于uboot的一些优化

    转载于:http://blog.163.com/solylee@126/blog/static/1718231572010101910485331/ 本人的开发环境是u-boot-1.1.6版本,fe ...

  2. 使用Aspectj 的配置文件方式进行aop操作

  3. 面试题: java面试经历 已看1 抢红包如何分配每个人抢到的钱 有用 难点的面试题

    2018.03.09 深圳乐唯科技 我看了下感觉这公司貌似挺不错的,面试官人也挺好的,氛围应该很不错,可惜我实力不足,唉,接续努力,下面把面试中印象较深的三个问题写一下. 面试问题1:数据库删除重复数 ...

  4. ZROI2018提高day4t2

    传送门 分析 我们二分球的直径,然后就像奶酪那道题一样,将所有距离相遇直径的点用并查集连在一起,然后枚举所有与上边的顶距离小于直径的点和所有与下边的距离小于直径的点,如果它们被并查集连在一起则代表这个 ...

  5. 构建一个在线ASCII视频流服务

    构建一个在线ASCII视频流服务 2018-03-26  正常的文章 1685 什么是ASCII视频流服务? 其实这个名字是咱胡乱起的,具体叫啥我也不清楚,但效果如下: 大家可以在自己的命令行里试下, ...

  6. 数学基础-3D空间的位置表示

    转自:http://www.cnblogs.com/gaoxiang12/p/5113334.html 刚体运动 本篇讨论一个很基础的问题:如何描述机器人的位姿.这也是SLAM研究的一个很基本的问题. ...

  7. html 里 checkbox里 只要选中就会自动添加checked=“checked”么?

    事实上HTML代码是不会发生变化的,但是控件对象的属性会发生变化以反映这个操作的结果.也就是说,该对象的checked属性值会由false变成true.但元素标签中并不会插入checked=" ...

  8. linux core文件机制

    在程序不寻常退出时,内核会在当前工作目录下生成一个core文件(是一个内存映像,同时加上调试信息).使用gdb来查看core文件,可以指示出导致程序出错的代码所在文件和行数. 1.core文件的生成开 ...

  9. MySQL中MyISAM引擎与InnoDB引擎性能简单测试

    [硬件配置]CPU : AMD2500+ (1.8G)内存: 1G/现代硬盘: 80G/IDE[软件配置]OS : Windows XP SP2SE : PHP5.2.1DB : MySQL5.0.3 ...

  10. 《Effective Java》第2章 创建和销毁对象

    第2条:遇到多个构造器参数时要考虑用构建器 与构造器相比,builder的微略优势在于,builder可以有多个可变(varargs)参数.构造器就像方法一样,只能有一个可变参数.因为builder利 ...