题意:有C头奶牛,K个挤奶站,每个挤奶器最多服务M头奶牛,奶牛和奶牛、奶牛和挤奶站、挤奶站和挤奶站之间都存在一定的距离。现在问满足所有的奶牛都能够被挤奶器服务到的情况下,行走距离的最远的奶牛的至少要走多远。题目给的邻接矩阵是K个挤奶站与C个奶牛的距离矩阵,其中0为不可达的意思。

刚刷网络流,第一次遇到这样题目,题意我就看了半天才懂。。此题需要将题给条件转化,最后利用二分枚举距离,将每次情况建立一个新的图再网络流得解。

思路: 需要首先用Floyd将各个站与奶牛的最短距离得出,然后利用二分,左边界=0,右边界=题给每条路最大权值*最大可能走的路数=200*(K+C)。

然后将每次枚举的mid比较图中的边权,因为要枚举的是最大距离(的最小值,但最大距离的性质肯定还是有的,即大于等于其他边),所以边权<=mid的加入网络流图中且权重为1,那些大于mid的边就当作该情况下不用走的,即可忽略。

将K与C以此建立网络流,并且设一个超级源点S与超级汇点T,S指向所有挤奶站K切边权为题给容量M,所有奶牛流向T边权为1。若最大流结果等于C说明该次枚举情况符合,便继续缩小枚举范围,若最大流结果小于C,说明边权限制过小则要增大枚举范围。一直反复枚举则得结果。

(代码转自https://www.cnblogs.com/Lyush/archive/2013/04/30/3052077.html)

 #include <cstdlib>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; int K, C, M; // K个挤奶器,C头奶牛,每个挤奶器最多M头奶牛共享
int N;
int mp[][]; struct Edge {
int v, c, next;
}; Edge e[];
int idx, head[];
int lv[];
int front, tail, que[];
const int SS = , TT = ;
const int INF = 0x3fffffff; void insert(int a, int b, int c) {
e[idx].v = b, e[idx].c = c;
e[idx].next = head[a];
head[a] = idx++;
} void floyd() { // 求出任意两点之间的最短路
for (int k = ; k <= N; ++k) {
for (int i = ; i <= N; ++i) {
if (mp[i][k] == INF || i == k) continue;
for (int j = ; j <= N; ++j) {
if (mp[k][j] == INF || j == k) continue;
mp[i][j] = min(mp[i][j], mp[i][k] + mp[k][j]);
}
}
}
} void build(int threshold) { // 阀值
idx = ;
memset(head, 0xff, sizeof (head));
for (int i = ; i <= K; ++i) {
insert(SS, i, M);
insert(i, SS, );
for (int j = K+; j <= N; ++j) {
if (mp[i][j] <= threshold) {
insert(i, j, );
insert(j, i, );
}
}
}
for (int i = K+; i <= N; ++i) {
insert(i, TT, );
insert(TT, i, );
}
} bool bfs() {
front = tail = ;
memset(lv, 0xff, sizeof (lv));
lv[SS] = ;
que[tail++] = SS;
while (front != tail) {
// printf("front = %d, tail = %d\n", front, tail);
int u = que[front++];
for (int i = head[u]; i != -; i = e[i].next) {
if (!(~lv[e[i].v]) && e[i].c) {
lv[e[i].v] = lv[u] + ;
if (e[i].v == TT) return true;
que[tail++] = e[i].v;
}
}
}
return ~lv[TT];
} int dfs(int u, int sup) {
if (u == TT) return sup;
int tf = , f;
for (int i = head[u]; i != -; i = e[i].next) {
if (lv[u]+==lv[e[i].v] && e[i].c && (f=dfs(e[i].v, min(e[i].c, sup-tf)))) {
tf += f;
e[i].c -= f, e[i^].c += f;
if (tf == sup) return sup;
}
}
if (!tf) lv[u] = -;
return tf;
} int dinic() {
int ret = ;
while (bfs()) {
ret += dfs(SS, INF);
}
return ret;
} int bsearch(int l, int r) {
int mid, ret;
while (l <= r) {
mid = (l + r) >> ;
if (build(mid), dinic() == C) {
ret = mid;
r = mid - ;
} else {
l = mid + ;
}
}
return ret;
} int main() {
while (scanf("%d %d %d", &K, &C, &M) != EOF) {
N = K+C;
memset(mp, , sizeof (mp));
for (int i = ; i <= N; ++i) {
for (int j = ; j <= N; ++j) {
scanf("%d", &mp[i][j]);
if (!mp[i][j]) mp[i][j] = INF;
}
}
floyd();
printf("%d\n", bsearch(, ));
}
return ;
}

POJ 2112 Optimal Milking 最短路 二分构图 网络流的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

    题目大意: 在一个农场里面,有k个挤奶机,编号分别是 1..k,有c头奶牛,编号分别是k+1 .. k+c,每个挤奶机一天最让可以挤m头奶牛的奶,奶牛和挤奶机之间用邻接矩阵给出距离.求让所有奶牛都挤到 ...

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

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

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

    题意: k c m 分别代表挤奶机数量,牛数量,和挤奶机容量. 接下来(n=k+c)n*n的矩阵A,代表挤奶机或者牛的距离,如果对角线都为0,如果非对角线没有直接路相连也为0. 1 <= K & ...

随机推荐

  1. Linux学习(二) --- 常用命令

    [TOC] 一.常用命令 1.目录 cd切换 cd 路径 切换到指定路径 cd .. 上一级 mkdir:创建目录 mkdir 目录名 pwd:查看 2.查看 ll命令:查询目录内容 ll 查看当前( ...

  2. Deep-Learning-with-Python] 文本序列中的深度学习

    https://blog.csdn.net/LSG_Down/article/details/81327072 将文本数据处理成有用的数据表示 循环神经网络 使用1D卷积处理序列数据 深度学习模型可以 ...

  3. myeclipse跟tomcat的同步

    一般来说,我们在myeclipse里把文件内容改了并保存之后,直接刷新网页就可以非常直观的看到内容的改变. 这是因为myeclipse检测到文件内容的变动,及时地把新的文件部署到了tomcat上. m ...

  4. windows之anaconda导入torch失败和pip install命令执行read time out

    昨天用jupyter导入torch还好好的呢,今天用就不行了,先是ImportError: DLL load failed: 找不到指定的模块.再是No such comm target regist ...

  5. 剑指offer【12】- 二进制中1的个数

    输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. public class Solution { public int NumberOf1(int n) { String str = ...

  6. jquery.marquee.js - 有点奇怪的跑马灯动画,不过还是加上去了

    客户想要一个跑马灯的效果,最终我用了jquery.marquee.js. 这个库很简单就能用. 效果是这样,从左到右,移动速度都不一样. 1. HTML <div class="mar ...

  7. Codeforces Round #316 (Div. 2) D计算在一棵子树内某高度的节点

    题:https://codeforces.com/contest/570/problem/D 题意:给定一个以11为根的n个节点的树,每个点上有一个字母(a~z),每个点的深度定义为该节点到11号节点 ...

  8. E - Ingredients 拓扑排序+01背包

    题源:https://codeforces.com/gym/101635/attachments 题意: n行,每行给定字符串s1,s2,s3代表一些菜谱名.s2和s3是煮成是的必要条件,然后给出c和 ...

  9. mysql 视图 事务 索引

    为什么需要有视图 * 对于复杂的查询,往往是有多个数据表进行关联查询而得到,而这种语句往往比较复杂,也可能非常频繁的使用. 比如这样的SQL语句 select goods.name,goods_cat ...

  10. regex(python)

    正则表达式 #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2018/7/26 16:39 # @Author : jackendoff ...