题目大意:

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

奶的情况下,走的最远的那头奶牛走的距离最小是多少。

数据保证有解。

算法讨论:

首先可以想到是二分,然后在选择流网络的时候,一开始选择的最小费用最大流,让二分的边权充当最小费用,但是这样跑发现每次二分的是我们要跑的答案,不可行。所以就改用最大流。

最大流肯定是在二分的情况下判定最大流是否等于c,即是否所有的奶牛都可以挤到奶,所以一开始我的做法是直接把所有的边都加进去,然后在跑bfs的时候把边权大于二分值的边卡掉,但是发现这样是不可行的,(至于为什么不可行,有待思考。。。。)然后另一种做法就是每一次二分的时候都是重新加边(当前是小于二分值的边),然后跑最大流。但是不知道为什么我跑出来那么的效率低下。加边就是这样加:从超级源点向每头牛加流量为1的边,每头牛向距离小于二分当前值的挤奶机加流量为1的边,每个挤奶机向超级汇点加流量为m的边,根据入流等于出流的原理,这样就可以保证每个挤奶机至多只挤m头牛的奶了。

Codes:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue> using namespace std; int k, c, mm, l, r, Mid;
int arr[][]; struct MF{
static const int N = + ;
static const int M = * + ;
static const int oo = 0x3f3f3f3f; int n, m, s, t, tot;
int first[N], next[M];
int u[M], v[M], cap[M], flow[M];
int dis[N], cur[N];
bool vi[M]; void Clear(){
tot = ;
memset(first, -, sizeof first);
memset(flow, ,sizeof flow);
}
void Add(int from, int to, int cp, int flw){
u[tot] = from; v[tot] = to; cap[tot] = cp; flow[tot] = flw;
next[tot] = first[u[tot]];
first[u[tot]] = tot;
++ tot;
}
bool bfs(){
memset(vi, false, sizeof vi); queue <int> q;
dis[s] = ;vi[s] = true;
q.push(s); while(!q.empty()){
int now = q.front();q.pop();
for(int i = first[now]; i != -; i = next[i]){
if(!vi[v[i]] && cap[i] > flow[i]){
vi[v[i]] = true;
dis[v[i]] = dis[now] + ;
q.push(v[i]);
}
}
}
return vi[t];
}
int dfs(int x, int a){
if(x == t || a == ) return a;
int flw = , f;
int &i = cur[x];
for(i = first[x]; i != -; i = next[i]){
if(dis[x] + == dis[v[i]] && (f = dfs(v[i], min(a, cap[i]-flow[i]))) > ){
flow[i] += f; flow[i^] -= f;
a -= f; flw += f;
if(a == ) break;
}
}
return flw;
}
int MaxFlow(int s, int t){
this->s = s;this->t = t;
int flw = ;
while(bfs()){
memset(cur, , sizeof cur);
flw += dfs(s, oo);
}
return flw;
}
}Net; void Floyed(){
for(int kk = ; kk <= k + c; ++ kk)
for(int i = ; i <= k + c; ++ i)
for(int j = ; j <= k + c; ++ j)
if(kk != i && i != j && kk != j)
if(arr[i][kk] < && arr[kk][j] < )
arr[i][j] = min(arr[i][j], arr[i][kk] + arr[kk][j]);
} bool check(){
Net.Clear();
for(int i = ; i <= c; ++ i){
Net.Add(, i + k, , );
Net.Add(i + k, , , );
}
for(int i = ; i <= k; ++ i){
Net.Add(i, Net.n + , mm, );
Net.Add(Net.n + , i, , );
}
for(int i = k + ; i <= k + c; ++ i){
for(int j = ; j <= k; ++ j){
if(arr[i][j] <= Mid){
Net.Add(i, j, , );
Net.Add(j, i, , );
}
}
}
if(Net.MaxFlow(, Net.n + ) == c) return true;
return false;
} void Solve(){
int ans=;l = ;r = ;
while(l <= r){
Mid = l + (r - l) / ;
if(check()){
ans = Mid;r = Mid - ;
}
else l = Mid + ;
}
printf("%d\n", ans);
}
int main(){ scanf("%d%d%d", &k, &c, &mm);
Net.n = k + c;
memset(arr, /, sizeof arr);
for(int i = ; i <= k + c; ++ i)
for(int j = ; j <= k + c; ++ j){
scanf("%d", &arr[i][j]);
arr[i][j] = arr[i][j] == ? Net.oo : arr[i][j];
}
Floyed();
Solve();
return ;
}

POJ 2112

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

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

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

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

    <题目链接> 题目大意: 有K台挤奶机和C头奶牛,都被视为物体,这K+C个物体之间存在路径.给出一个 (K+C)x(K+C) 的矩阵A,A[i][j]表示物体i和物体j之间的距离,有些物体 ...

  3. POJ 2112 Optimal Milking(最大流)

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

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

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

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

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

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

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

  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——————【多重匹配、二分枚举答案、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. Oracle11g R2学习系列 之十 解决EM不能用

    不知道是什么原因https://localhost:1158/em,今天突然就不能用了.做了好多搜索也没有解决.现象是在services.msc中,不能重启OracleDBConsole服务,提示: ...

  2. HTML5视频

    <video>标签用于定义视频. 案例1: <!DOCTYPE html><html><head lang="en"> <me ...

  3. 更快的方式实现PHP数组去重(转)

    概述 使用PHP的array_unique()函数允许你传递一个数组,然后移除重复的值,返回一个拥有唯一值的数组.这个函数大多数情况下都能工作得很好.但是,如果你尝试在一个大的数组里使用array_u ...

  4. 【笔记】Linux 和 Unix 作业控制

    Linux 和 Unix 属于多任务的操作系统,也就是说一个系统在同一时间段内能运行多重任务(进程). 作业控制不只是能够停止/挂起(stop/suspend)正在执行的进程(命令),也可以继续/唤醒 ...

  5. C语言读写伯克利DB 4

    因为缓存数据的buffer总是不够大(会引起段错误)索性从堆上拿了两块大内存 /* 功能说明:逐日存储来访用户(使用伯克利DB) 根据存储的用户信息确定某用户是否是首次来访用户(未被存储的伯克利DB) ...

  6. AQS详解

    一.概述 谈到并发,不得不谈ReentrantLock:而谈到ReentrantLock,不得不谈AbstractQueuedSynchronized(AQS)! 类如其名,抽象的队列式的同步器,AQ ...

  7. 通用多目录makefile的写法

    我的项目文件层次是:项目名称/include.output.src src/admin.stu.tch.common 最外层的Makefile: DEBUG = yMYDEBUG = DEBUGife ...

  8. Jquery 概念性内容编辑器

      概念性jQuery内容编辑器,这是一款非常有特色的jQuery编辑器,该编辑器支持文字.列表.视频.引用等功能,是一款小巧简洁,富有个性化的jQuery内容编辑器插件. 代码: <!doct ...

  9. ECharts JavaScript图表库 ECharts

    ECharts开源来自百度商业前端数据可视化团队,基于html5 Canvas,是一个纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表.创新的拖拽重计算.数据视图.值 ...

  10. LLVM安装

    cd ~tar -vzxf llvm-3.3.src.tar.gzmv llvm-3.3.src llvmcd llvm/tools/tar -vzxf cfe-3.3.src.tar.gzmv cf ...