<题目链接>

题目大意:

  有K台挤奶机和C头奶牛,都被视为物体,这K+C个物体之间存在路径。给出一个 (K+C)x(K+C) 的矩阵A,A[i][j]表示物体i和物体j之间的距离,有些物体之间可能没有直接通路。 每台挤奶机可以容纳m头奶牛去挤奶,且每个奶牛仅可以去往一台挤奶机。现在安排这C头奶牛去挤奶,每头奶牛会去往某个挤奶机,求出这C头奶牛去其挤奶的最长路径的最小值。

解题分析:
  因为要求最长路径的最小值,所以我们很容易想到二分答案。由于数据量较小,所以我们先用floyed求出所有点之间的最短距离,然后直接二分答案,枚举最长路径的最小值,再根据枚举的值建图,源点向所有机器连一条容量为m的边,所有的牛向汇点连一条容量为1的边,并且距离<=枚举值的机器与牛连一条容量为1的边,最后求最大流,如果最大流==c,则成立。

 #include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <iostream>
using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++)
typedef long long LL;
const int MX = ;
const int MXE = * MX * MX;
const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;
const int INF = 0x3f3f3f3f;
int mp[][];
int k, c, m,maxdist;
struct MaxFlow {
struct Edge {
int v, nxt;
LL w;
} E[MXE];
int tot, num, s, t;
int head[MX];
void init() {
memset (head, -, sizeof (head) );
tot = ;
}
void add (int u, int v, LL w) {
E[tot].v=v,E[tot].nxt=head[u],E[tot].w=w;
head[u] = tot++; E[tot].v=u,E[tot].nxt=head[v],E[tot].w=;
head[v] = tot++;
}
int d[MX], vis[MX], gap[MX];
void bfs() {
memset (d, , sizeof (d) );
memset (gap, , sizeof (gap) );
memset (vis, , sizeof (vis) );
queue<int>q;
q.push (t);
vis[t] = ;
while (!q.empty() ) {
int u = q.front();
q.pop();
for (int i = head[u]; ~i; i = E[i].nxt) {
int v = E[i].v;
if (!vis[v]) {
d[v] = d[u] + ;
gap[d[v]]++;
q.push (v);
vis[v] = ;
}
}
}
}
int last[MX];
LL dfs (int u, LL f) {
if (u == t) return f;
LL sap = ;
for (int i = last[u]; ~i; i = E[i].nxt) {
int v = E[i].v;
if (E[i].w > && d[u] == d[v] + ) {
last[u] = i;
LL tmp = dfs (v, min (f - sap, E[i].w) );
E[i].w -= tmp;
E[i ^ ].w += tmp;
sap += tmp;
if (sap == f) return sap;
}
}
if (d[s] >= num) return sap;
if (! (--gap[d[u]]) ) d[s] = num;
++gap[++d[u]];
last[u] = head[u];
return sap;
}
LL solve (int st, int ed, int n) {
LL flow = ;
num = n;s = st;t = ed;
bfs();
memcpy (last, head, sizeof (head) );
while (d[s] < num) flow += dfs (s, INFLL);
return flow;
}
}Maxflow; int MaxFlow_check(int mid) { //建图,跑最大流
Maxflow.init(); //初始化
for (int i = ; i <= k ; i++) {
Maxflow.add(, i, m); //源点与机器相连,容量为m
for (int j = k + ; j <= k + c ; j++ )
if (mp[i][j] <= mid) Maxflow.add(i, j, ); //机器与牛相连,容量为1
}
for (int i = k + ; i <= k + c ; i++)
Maxflow.add(i, k + c + , ); //牛与汇点相连,容量为1
if ((int)(Maxflow.solve( , k + c + , k + c + )) == c) return ;
return ;
}
void Floyed(int n){
rep(k,,n) rep(i,,n) rep(j,,n){
mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]);
maxdist=max(maxdist,mp[i][j]); //找到最大的mp[i][j],为寻找二分的上界
}
}
int main() {
while(~scanf("%d%d%d", &k, &c, &m)) {
for (int i = ; i <= k + c ; i++)
for (int j = ; j <= k + c ; j++) {
scanf("%d", &mp[i][j]);
if (i != j && !mp[i][j]) mp[i][j] = INF; //将0置为不可达
}
maxdist=-INF;Floyed(k+c);
int l = , r = maxdist ,ans = ;
while(l <= r) {
int mid = (l + r) >> ;
if (MaxFlow_check(mid))ans = mid,r = mid - ;
else l = mid + ;
}
printf("%d\n", ans);
}
return ;
}

2018-11-24

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

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

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

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

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

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

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

  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【网络流+二分+最短路】

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

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

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

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

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

随机推荐

  1. java基础题刷题中的知识点复习

    将变量转换为字符串方法:(String)待转对象..toString().String.valueOf(待转对象) 对字符串进行操作的方法,使用StringBuffer和StringBuilder定义 ...

  2. 《MySQL5.7从入门到精通(视频教学版)》

    · 一:书籍PDF获取途径 pdf 文档 在 此QQ群(668345923) 的群文件里面 学习视频资源 二:书籍介绍 本书主要包括MySQL的安装与配置.数据库的创建.数据表的创建.数据类型和运算符 ...

  3. ORACLE in与exists语句的区别

    select * from A where id in(select id from B) 以上查询使用了in语句,in()只执行一次,它查出B表中的所有id字段并缓存起来.之后,检查A表的id是否与 ...

  4. vue.js的计算机属性学习

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  5. 1873: This offer(zzuli)

    题目描述 话说WX入职已经有一个多月了,公司boss突然扔给他了一个问题,如果解决不了的话就会被开除掉 - -#,情急之下他只能来请教你了,boss给了他N个不大于100的数,现在wx需要将这N个数通 ...

  6. Fatal error: Uncaught Error: Call to undefined function mysqli_connect()

    sudo apt-get install php7.2-mysql  //版本号肯能不一样 sudo dpkg-reconfigure  php7.2-mysql sudo /etc/init.d/m ...

  7. Python函数之匿名函数

    一:概述 匿名函数主要用来处理比较简单的逻辑,用一行显示,并将运算结果作为返回值返回 二:书写规则 函数名 = lambda 参数:返回值 参数可以有多个,多个参数使用逗号分隔 三 :例子 将func ...

  8. Nginx配置TCP请求转发

    Nginx配置TCP请求转发 1.TCP请求转发基于stream在1.9版本前,需要单独编译安装该组建: # 依赖服务 [root@baolin conf]#yum -y install pcre-d ...

  9. Ubuntu点击dash home就崩溃

    很崩溃的一个问题,搞了好久.并没有很清楚的知道具体哪个细节导致的问题,只是大概知道了原因,以及搞出了一个解决方案. 问题描述 台式机,没有独立显卡,也就是只有一个intel CPU在一起的小破显卡(我 ...

  10. zeromq的安装,部署(号称最快的消息队列,消息中间件)

    1:Storm作为一个实时处理的框架,产生的消息需要快速的进行处理,比如存在消息队列ZeroMQ里面. 由于消息队列ZeroMQ是C++写的,而我们的程序是运行在JVM虚拟机里面的.所以需要jzmq这 ...