POJ 2112 Optimal Milking (二分 + 最大流)
题目大意:
在一个农场里面,有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 (二分 + 最大流)的更多相关文章
- POJ 2112 Optimal Milking ( 经典最大流 && Floyd && 二分 )
题意 : 有 K 台挤奶机器,每台机器可以接受 M 头牛进行挤奶作业,总共有 C 头奶牛,机器编号为 1~K,奶牛编号为 K+1 ~ K+C ,然后给出奶牛和机器之间的距离矩阵,要求求出使得每头牛都能 ...
- POJ 2112 Optimal Milking (二分+最短路+最大流)
<题目链接> 题目大意: 有K台挤奶机和C头奶牛,都被视为物体,这K+C个物体之间存在路径.给出一个 (K+C)x(K+C) 的矩阵A,A[i][j]表示物体i和物体j之间的距离,有些物体 ...
- POJ 2112 Optimal Milking(最大流)
题目链接:http://poj.org/problem?id=2112 Description FJ has moved his K (1 <= K <= 30) milking mach ...
- POJ 2112.Optimal Milking (最大流)
时间限制:2s 空间限制:30M 题意: 有K台挤奶机(编号1~K),C头奶牛(编号K+1~K+C),给出各点之间距离.现在要让C头奶牛到挤奶机去挤奶,每台挤奶机只能处理M头奶牛,求使所走路程最远的奶 ...
- POJ 2112 Optimal Milking (二分 + floyd + 网络流)
POJ 2112 Optimal Milking 链接:http://poj.org/problem?id=2112 题意:农场主John 将他的K(1≤K≤30)个挤奶器运到牧场,在那里有C(1≤C ...
- POJ 2112 Optimal Milking (二分+最短路径+网络流)
POJ 2112 Optimal Milking (二分+最短路径+网络流) Optimal Milking Time Limit: 2000MS Memory Limit: 30000K To ...
- Poj 2112 Optimal Milking (多重匹配+传递闭包+二分)
题目链接: Poj 2112 Optimal Milking 题目描述: 有k个挤奶机,c头牛,每台挤奶机每天最多可以给m头奶牛挤奶.挤奶机编号从1到k,奶牛编号从k+1到k+c,给出(k+c)*(k ...
- POJ 2112—— Optimal Milking——————【多重匹配、二分枚举答案、floyd预处理】
Optimal Milking Time Limit:2000MS Memory Limit:30000KB 64bit IO Format:%I64d & %I64u Sub ...
- POJ 2112 Optimal Milking (Dinic + Floyd + 二分)
Optimal Milking Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 19456 Accepted: 6947 ...
随机推荐
- C++中引用和指针详解
先来分析指针这个东东: 从概念上讲,指针本质上就是存放变量地址的一个变量,在逻辑上是独立的,它可以被改变,包括其所指向的地址的改变和其指向的地址中所存放的数据的改变. 上面的图表示了程序运行时变量的值 ...
- win8(64位)下memcache安装时报错“ failed to install service or service already installed” 与安装
解决办法: 1.找到cmd.exe文件(c:\windows\system32\cmd.exe) 2.右键cmd.exe以管理员方式运行 3.把php_memcache.dll放到php的ext目录: ...
- python3.4入门——核心数据类型
变量.对象和引用 变量的创建:一个变量(即变量名,如a),当代码第一次给它赋值就创建了它. 变量类型:变量没有任何和它关联的类型信息约束.类型的概念存在于对象中,而不是变量名中.变量原本是通用的,只是 ...
- 在子jsp页面中调用父jsp中的function或父jsp调用子页面中的function
项目场景: A.jsp中有一个window,window里嵌入了一个<iframe>,通过<iframe>引入了另一个页面B.jsp.在B.jsp中的一个function中需要 ...
- 函数:递归是神马 - 零基础入门学习Python022
函数:递归是神马 让编程改变世界 Change the world by program 我们这节课的主题叫递归是神马,将通过小甲鱼带感的讲解,来告诉大家神马是递归!如果说优秀的程序员是伯乐,那么把递 ...
- WordPress插件开发记录
1.a标签在新的网页中打开内容 <a href="网址" target="_blank"></a> 2.PDO的$re ...
- Codeforces 463D Gargari and Permutations
http://codeforces.com/problemset/problem/463/D 题意:给出k个排列,问这k个排列的最长公共子序列的长度. 思路:只考虑其中一个的dp:f[i]=max(f ...
- BZOJ 3550 Vacation
http://www.lydsy.com/JudgeOnline/problem.php?id=3550 题意:有3N个数,你需要选出一些数,首先保证任意长度为N的区间中选出的数的个数<=K个, ...
- Hdu2437-Jerboas(取余数判重搜索)
Jerboas are small desert-living animals, which resemble mice with a long tufted tail and very long h ...
- FFmpeg缩放swscale详解 <转>
利用ffmpeg进行图像数据格式的转换以及图片的缩放应用中,主要用到了swscale.h文件中的三个函数,分别是: struct SwsContext *sws_getContext(int srcW ...