<题目链接>

题目大意:

  有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. ssh: connect to host github.com port 22: Connection timed out

    问题描述 $ git clone git@github.com:MaugerWu/MaugerWu.github.io.git Cloning into 'MaugerWu.github.io'... ...

  2. 前端图片缓存之通过img标签加载GIF只能播放一次问题(转载)

    最近项目中要求再网页中插入一张gif图片,让用户每次到达该位置时动一次,所以我们就制作了一张只动一次的gif图片通过img标签引入.当用户进入该位置时,通过remove()清除图片然后重新append ...

  3. django中数据库的配置及相关增删改查

    ORM ORM是什么?:(在django中,根据代码中的类自动生成数据库的表也叫--code first) ORM:Object Relational Mapping(关系对象映射) 类名对应---- ...

  4. 基于Form组件实现的增删改和基于ModelForm实现的增删改

    一.ModelForm的介绍 ModelForm a. class Meta: model, # 对应Model的 fields=None, # 字段 exclude=None, # 排除字段 lab ...

  5. (批量更新)对多个符合条件的id做更新操作

    需求描述:把checkbox勾选的对应id的记录的标志位置1或0,这个其实不难的,不过我自己做的话,肯定是多次访问数据库做更新,看了老大的代码,发现差距不是一般的大,老大把sql灵活运用,结果一次访问 ...

  6. laravel 5 优化

    性能一直是 Laravel 框架为人诟病的一个点,所以调优 Laravel 程序算是一个必学的技能. 接下来分享一些开发的最佳实践,还有调优技巧,大家有别的建议也欢迎留言讨论. 这里是简单的列表: 配 ...

  7. 基于Web的漏洞利用

    1.Nikto 基于Web的漏洞信息扫描 nikto 自动扫描web服务器上没有打补丁的软件,同时同时也检测驻留在服务器上的危险文件,nikto能够识别出特定的问题,检测服务器的配置问题, 检测某台主 ...

  8. mybatis-查询过程

    基本的查询过程: sqlsession--->executor---->statementhandler---->statement----->db InputStream r ...

  9. linux 将自己的服务添加到系统service服务

    前言 我们在linux上要启动一个程序得时候, 往往都是要写一堆路径, 找到要启动得服务程序, 再用 ./*** 启动服务. 那么我们有没有快速启动方法吗, 答案是肯定得 service 介绍 官方介 ...

  10. truncate table时存在外键约束的解决办法

    以前在使用truncate命令时遇到表存在外键引用时无法执行命令的情况都是用delete来代替,今天又遇到这个问题,于是在网上搜了一把,可以通过如下方式解决: 1.基本思路:先关闭mysql的外键约束 ...