题目大意:

在一个农场里面,有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. Oracle 账户被锁定

    哎 每次安装oracle的时候总是忘了将用户解锁,结果就蛋疼了,从网上找到一个简单的解决方案 在CMD命令输出如下: sqlplus /nolog alert user system account ...

  2. hdu 2564 词组缩写

    Problem Description 定义:一个词组中每个单词的首字母的大写组合称为该词组的缩写. 比如,C语言里常用的EOF就是end of file的缩写. Input 输入的第一行是一个整数T ...

  3. sqlite编译

    1.下载代码:http://www.sqlite.org/download.html ,windows下下载sqlite-amalgamation-xxx.zip和sqlite-dll-win32-x ...

  4. 在java中生成二维码,并直接输出到jsp页面

    在java中生成的二维码不存到磁盘里要直接输出到页面上,这就需要把生成的二维码直接以流的形式输出到页面上,我用的是myeclipse 和 tomcat 它的原理是:在加载页面时,根据img的src(c ...

  5. 【Nutch2.3基础教程】集成Nutch/Hadoop/Hbase/Solr构建搜索引擎:安装及运行【集群环境】

    1.下载相关软件,并解压 版本号如下: (1)apache-nutch-2.3 (2) hadoop-1.2.1 (3)hbase-0.92.1 (4)solr-4.9.0 并解压至/opt/jedi ...

  6. 使用json常用到的包有以下六个

    使用json常用到的包有以下六个 1. commons-logging-1.0.4.jar 2. commons-lang-2.3.jar 3. commons-collections-3.2.jar ...

  7. map和reduce

    map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回. map()传入的第一个参数是f,即函数对象本身.由于 ...

  8. IIS 7.0 的 ASP.NET 应用程序生命周期概述(转载)

    IIS 7.0 的 ASP.NET 应用程序生命周期概述更新:2007 年 11 月本主题介绍在 IIS 7.0 集成模式下运行以及与 IIS 7.0 或更高版本一起运行的 ASP.NET 应用程序的 ...

  9. C语言-cout<<"123"<<"45"<<endl;

    VC中头文件为:#include <iostream.h> 这个在c中没有.是C++引进的. cout<头文件#include中printf()类似. 只是不需要标明数据类型. en ...

  10. Could not find qmake configuration file win32-g++

    D:\Source>c:\Qt\Qt5.3.2_static\bin\qmake -makefile -o Makefile my.proCould not find qmake configu ...