链接:http://poj.org/problem?id=2112

题意:有k个挤奶器。编号1~k,c头牛,编号k+1~k+c,每一个挤奶器最多能给m头牛挤奶,给你一个k+c的邻接矩阵。要求每头牛都能挤奶而且要求c头牛须要走的全部路程中的最大路程最小,求这个最小的路。

思路:

1. 先用floyd处理出多源最短路

2. 用二分枚举答案的可能。初始上限应该为(200+30)*200。可是我这么开T了,可能由于代码太挫,改到1000,卡着时间过了,仅仅能说poj数据弱了。后来看别人的代码。和我的做法一样可是用了邻接表。就能设上限为40000了。在二分中:

(1)构造容量网络,以0点为源点。到每头牛的容量为1。以n+1点为汇点。每一个挤奶器到汇点的容量为m,当然反过来也能够,由于源点和汇点的流量是相等的(等于c)。对于每头牛和每一个挤奶器之间的距离,假设比枚举的距离还大。则容量为0,否则容量为1。

(2)Dinic找出网络最大流,非常明显最大流最大是c,当最大流是c的时候是一种答案。但不一定是最优。更新二分上限。假设最大流没达到c,则更新下限。

这是做完POJ2391知道了Dinic优化。改进后的写法。优化了三个地方:容量网络改为邻接表、Dinic优化、二分上限从floyd中返回,157MS ,我原以为Dinic优化应该是效率提高的主要原因。把Dinic优化去掉单纯用邻接表。266MS。原来邻接表才是这道题效率提高的主要原因,可是Dinic优化还是非常实用的。

假设floyd再加个剪枝,能够跑110MS

  1. #include<cstring>
  2. #include<string>
  3. #include<fstream>
  4. #include<iostream>
  5. #include<iomanip>
  6. #include<cstdio>
  7. #include<cctype>
  8. #include<algorithm>
  9. #include<queue>
  10. #include<map>
  11. #include<set>
  12. #include<vector>
  13. #include<stack>
  14. #include<ctime>
  15. #include<cstdlib>
  16. #include<functional>
  17. #include<cmath>
  18. using namespace std;
  19. #define PI acos(-1.0)
  20. #define MAXN 200100
  21. #define eps 1e-7
  22. #define INF 0x7FFFFFFF
  23. #define LLINF 0x7FFFFFFFFFFFFFFF
  24. #define seed 131
  25. #define mod 1000000007
  26. #define ll long long
  27. #define ull unsigned ll
  28. #define lson l,m,rt<<1
  29. #define rson m+1,r,rt<<1|1
  30.  
  31. struct node{
  32. int u,w,next;
  33. }edge[MAXN];
  34. int head[350],e[350][350];
  35. int dist[350];
  36. int cnt,n,m,k,c,src,sink;
  37. void add_edge(int a,int b,int c){
  38. edge[cnt].u = b;
  39. edge[cnt].w = c;
  40. edge[cnt].next = head[a];
  41. head[a] = cnt++;
  42. }
  43. int floyd(){
  44. int i,j,k;
  45. int maxm = 0;
  46. for(k=1;k<=n;k++){
  47. for(i=1;i<=n;i++){
  48. if(e[i][k]==INF) continue;
  49. for(j=1;j<=n;j++){
  50. if(e[k][j]!=INF&&e[i][k]+e[k][j]<e[i][j]){
  51. e[i][j] = e[i][k] + e[k][j];
  52. if(e[i][j]>maxm) maxm = e[i][j];
  53. }
  54. }
  55. }
  56. }
  57. return maxm;
  58. }
  59. void build_graph(int minm){
  60. int i,j;
  61. memset(head,-1,sizeof(head));
  62. cnt = 0;
  63. for(i=1;i<=k;i++){
  64. add_edge(i,n+1,m);
  65. add_edge(n+1,i,0);
  66. }
  67. for(i=k+1;i<=n;i++){
  68. add_edge(0,i,1);
  69. add_edge(i,0,0);
  70. }
  71. for(i=k+1;i<=n;i++){
  72. for(j=1;j<=k;j++){
  73. if(e[i][j]<=minm){
  74. add_edge(i,j,1);
  75. add_edge(j,i,0);
  76. }
  77. }
  78. }
  79. }
  80. int bfs(){
  81. int i,j;
  82. memset(dist,-1,sizeof(dist));
  83. queue<int>q;
  84. q.push(0);
  85. dist[0] = 1;
  86. while(!q.empty()){
  87. int t = q.front();
  88. q.pop();
  89. for(i=head[t];i!=-1;i=edge[i].next){
  90. if(dist[edge[i].u]==-1&&edge[i].w){
  91. dist[edge[i].u] = dist[t] + 1;
  92. q.push(edge[i].u);
  93. }
  94. }
  95. }
  96. if(dist[n+1]!=-1) return 1;
  97. else return 0;
  98. }
  99. int dfs(int u,int delta){
  100. int i,j;
  101. int dd;
  102. if(u==n+1) return delta;
  103. for(i=head[u];i!=-1;i=edge[i].next){
  104. if(dist[edge[i].u]==dist[u]+1&&edge[i].w&&(dd = dfs(edge[i].u,min(edge[i].w,delta)))){
  105. edge[i].w -= dd;
  106. edge[i^1].w += dd;
  107. return dd;
  108. }
  109. }
  110. dist[u] = -1;
  111. return 0;
  112. }
  113. int main(){
  114. int i,j;
  115. while(scanf("%d%d%d",&k,&c,&m)!=EOF){
  116. n = k + c;
  117. for(i=1;i<=n;i++){
  118. for(j=1;j<=n;j++){
  119. scanf("%d",&e[i][j]);
  120. if(e[i][j]==0) e[i][j] = INF;
  121. }
  122. }
  123. int mid, l = 0,r=floyd();
  124. int sum,temp;
  125. while(l<r){
  126. mid = (l+r)/2;
  127. sum = 0;
  128. build_graph(mid);
  129. while(bfs()){
  130. while(1){
  131. temp = dfs(0,INF);
  132. if(!temp) break;
  133. sum += temp;
  134. }
  135. }
  136. if(sum>=c) r = mid;
  137. else l = mid + 1;
  138. }
  139. printf("%d\n",l);
  140. }
  141. return 0;
  142. }

之前的写法,1875MS擦边过了。

  1. #include<cstring>
  2. #include<string>
  3. #include<fstream>
  4. #include<iostream>
  5. #include<iomanip>
  6. #include<cstdio>
  7. #include<cctype>
  8. #include<algorithm>
  9. #include<queue>
  10. #include<map>
  11. #include<set>
  12. #include<vector>
  13. #include<stack>
  14. #include<ctime>
  15. #include<cstdlib>
  16. #include<functional>
  17. #include<cmath>
  18. using namespace std;
  19. #define PI acos(-1.0)
  20. #define MAXN 50100
  21. #define eps 1e-7
  22. #define INF 0x7FFFFFFF
  23. #define seed 131
  24. #define mod 1000000007
  25. #define ll long long
  26. #define ull unsigned ll
  27. #define lson l,m,rt<<1
  28. #define rson m+1,r,rt<<1|1
  29.  
  30. int edge[300][300],customer[300][300];
  31. int vis[300],dist[300][300];
  32. int n,m,k,c;
  33. void floyd(){
  34. int i,j,k;
  35. for(k=1;k<=n;k++){
  36. for(i=1;i<=n;i++){
  37. for(j=1;j<=n;j++){
  38. if(edge[i][k]!=INF&&edge[k][j]!=INF&&edge[i][k]+edge[k][j]<edge[i][j])
  39. edge[i][j] = edge[i][k] + edge[k][j];
  40. }
  41. }
  42. }
  43. }
  44. void build_graph(int minm){
  45. int i,j;
  46. memset(customer,0,sizeof(customer));
  47. for(i=1;i<=k;i++) customer[i][n+1] = m;
  48. for(i=k+1;i<=n;i++) customer[0][i] = 1;
  49. for(i=k+1;i<=n;i++){
  50. for(j=1;j<=k;j++){
  51. if(edge[i][j]<=minm) customer[i][j] = 1;
  52. }
  53. }
  54. }
  55. int bfs(){
  56. int i,j;
  57. memset(vis,0,sizeof(vis));
  58. memset(dist,0,sizeof(dist));
  59. queue<int>q;
  60. q.push(0);
  61. vis[0] = 1;
  62. while(!q.empty()){
  63. int t = q.front();
  64. q.pop();
  65. for(i=0;i<=n+1;i++){
  66. if(!vis[i]&&customer[t][i]){
  67. vis[i] = 1;
  68. dist[t][i] = 1;
  69. q.push(i);
  70. }
  71. }
  72. }
  73. if(vis[n+1]) return 1;
  74. else return 0;
  75. }
  76. int dfs(int u,int delta){
  77. int i,j,s;
  78. if(u==n+1) return delta;
  79. s = delta;
  80. for(i=0;i<=n+1;i++){
  81. if(dist[u][i]){
  82. int dd = dfs(i,min(customer[u][i],delta));
  83. customer[u][i] -= dd;
  84. customer[i][u] += dd;
  85. delta -= dd;
  86. }
  87. }
  88. return s - delta;
  89. }
  90. int main(){
  91. int i,j;
  92. while(scanf("%d%d%d",&k,&c,&m)!=EOF){
  93. n = k + c;
  94. for(i=1;i<=n;i++){
  95. for(j=1;j<=n;j++){
  96. scanf("%d",&edge[i][j]);
  97. if(edge[i][j]==0) edge[i][j] = INF;
  98. }
  99. }
  100. floyd();
  101. int mid, l = 0, r = 10000;
  102. int sum;
  103. while(l<r){
  104. mid = (l+r)/2;
  105. sum = 0;
  106. build_graph(mid);
  107. while(bfs()) sum += dfs(0,INF);
  108. if(sum==c) r = mid;
  109. else l = mid + 1;
  110. }
  111. printf("%d\n",l);
  112. }
  113. return 0;
  114. }

POJ--2112--Optimal Milking【Floyd+Dinic+二分答案】的更多相关文章

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

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

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

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

  3. POJ 2112 Optimal Milking【网络流+二分+最短路】

    求使所有牛都可以被挤牛奶的条件下牛走的最长距离. Floyd求出两两节点之间的最短路,然后二分距离. 构图: 将每一个milking machine与源点连接,边权为最大值m,每个cow与汇点连接,边 ...

  4. POJ 2112 Optimal Milking 最短路 二分构图 网络流

    题意:有C头奶牛,K个挤奶站,每个挤奶器最多服务M头奶牛,奶牛和奶牛.奶牛和挤奶站.挤奶站和挤奶站之间都存在一定的距离.现在问满足所有的奶牛都能够被挤奶器服务到的情况下,行走距离的最远的奶牛的至少要走 ...

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

    题目链接 测试dinic模版,不知道这个模版到底对不对,那个题用这份dinic就是过不了.加上优化就WA,不加优化TLE. #include <cstdio> #include <s ...

  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 题目描述: 有k个挤奶机,c头牛,每台挤奶机每天最多可以给m头奶牛挤奶.挤奶机编号从1到k,奶牛编号从k+1到k+c,给出(k+c)*(k ...

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

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

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

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

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

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

随机推荐

  1. Linux下把目录拷贝到全部同名目录的脚本

    需求:拷贝文件夹到Linux文件夹下.覆盖该Linux文件夹下全部同名文件夹 目标:Linux下,运行本脚本.输入目录名.就可以批量复制覆盖. 使用说明:         先把本脚本文件和要复制的文件 ...

  2. luogu2754 星际转移问题 网络流

    题目大意:地球与月球间有可容纳无限人的太空站,还有在太空站与星球间按周期行驶的.有固定容量的太空船,每一艘太空船从一个太空站驶往任一太空站耗时均为 1.地球上有一定数量的人,问所有人到月球最少需要多少 ...

  3. 11.修改WSDL文档

    http://localhost:8077/person?wsdl可以由你来控制的.拿Person这个例子来说.

  4. 如何用ajax写分页查询(以留言信息为例)-----2017-05-17

    要写分页,首先你得清楚,一页你想显示多少条信息?如何计算总共显示的页数? 先说一下思路: (1)从数据库读取数据,以chenai表为例,读取所有留言信息.并能够实现输入发送者,可以查询该发送者的留言总 ...

  5. MVC学习日记(三)EntityFramework

    其实学会了第一篇的创建和第二篇的使用以后,基本的mvc操作足够了,至于验证神马的,还不如用Jquery.h5的好看适用,所以接下来, 后续上会讲一些比较实用的. 在之前的文章说到了基础的使用, 那么, ...

  6. python ansible api

    #!/usr/bin/env python # -*- coding: utf-8 -*- # @File : test2.py # @Author: Anthony.waa # @Date : 20 ...

  7. zookeeper单机和奇数集群

    zookeeper单机和奇数集群 链接地址:https://www.cnblogs.com/lsdb/p/7297731.html

  8. Codeforces Round #454

    Masha and Bears Tic-Tac-Toe Shockers Seating of Students Party Power Tower Reverses

  9. 高德地图修改gps定位点样式

    效果图 navi_map_gps_locked.png 图片1 图片2 修改 MyLocationStyle myLocationStyle = new MyLocationStyle();//初始化 ...

  10. Scala 大数据 常用算法收集

    一:IP转数字,用于比大小,用在求IP段范围中 def ip2Long(ip: String): Long = { val fragments = ip.split("[.]") ...