题目大意:K个挤奶机,C头牛,每个挤奶机最多可以接待M头牛,各个K,C之间可能有道路连接,要让每个牛都找到挤奶机,求最小的走的路程最远的牛所需走的距离。

思路:首先看到要最小化最大值,所以需要二分。可以先用Floyd算法预处理出个点之间最短距离。之后来进行二分的判断,对于每个牛都要匹配到一个挤奶机,而每个挤奶机可以匹配多头牛,所以可以用二分图匹配,建立源汇点S,T,S与每个牛连一条cap为1的边,而每台挤奶机要与T连一条cap为M的边。对于每个要判断的距离,如果牛-挤奶机之间的距离小于此,就连一条边,否则不连边。之后求最大流即可,如果正好等于C,也就是所有牛都完成匹配,说明判断的这个距离可行。

代码:

//POJ.2112
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0) typedef long long ll;
#define INF 0x3f3f3f3f
const int maxv = 1010; int V;
int D[maxv][maxv]; int K, C, M; struct edge {
int to, cap, rev;
}; vector<edge> G[maxv];
int level[maxv];
int iter[maxv]; void add_edge(int from, int to, int cap)
{
G[from].push_back(edge{ to, cap, (int)G[to].size() });
G[to].push_back(edge{ from, 0, (int)G[from].size() - 1 });
} void bfs(int s)
{
memset(level, -1, sizeof(level));
queue<int> que;
level[s] = 0;
que.push(s);
while (!que.empty())
{
int v = que.front();
que.pop();
for (int i = 0; i < G[v].size(); i++)
{
edge& e = G[v][i];
if (e.cap > 0 && level[e.to] < 0)
{
level[e.to] = level[v] + 1;
que.push(e.to);
}
}
}
} int dfs(int v, int t, int f)//找增广路
{
if (v == t)
return f;
for (int& i = iter[v]; i < G[v].size(); i++)
{
edge& e = G[v][i];
if (e.cap > 0 && level[v] < level[e.to])
{
int d = dfs(e.to, t, min(f, e.cap));
if (d > 0)
{
e.cap -= d;
G[e.to][e.rev].cap += d;
return d;
}
}
} return 0;
} int max_flow(int s, int t)
{
int flow = 0;
for (;;)
{
bfs(s);
if (level[t] < 0)
return flow;
memset(iter, 0, sizeof(iter));
int f;
while ((f = dfs(s, t, 0x3f3f3f3f3f3f3f3f)) > 0)
flow += f;
}
} bool E(int f)//看最多仅需f距离是否可行
{
//S=V,T=V+1
for (int i = 0; i < V + 2; i++)//最大流建图
G[i].clear();
for (int i = 0; i < K; i++)//挤奶-T连边
add_edge(i, V + 1, M);
for (int i = K; i < V; i++)//S-牛连边
add_edge(V, i, 1);
for (int i = 0; i < K; i++)//牛-挤奶之间,如果最短路小于f,连边容量1,否则不连边(只看《=f的边)
{
for (int j = K; j < V; j++)
{
if (D[j][i] <= f)
add_edge(j, i, 1);
}
}
return max_flow(V, V + 1) == C;
} void FloydWarshell()
{ for (int k = 0; k < V; k++)
{
for (int i = 0; i < V; i++)
{
for (int j = 0; j < V; j++)
D[i][j] = min(D[i][j], D[i][k] + D[k][j]);
}
}
} void solve()
{
FloydWarshell();
int lo = 0, hi = 1000 * V;
while (hi - lo > 1)
{
int mi = (lo + hi) / 2;
if (E(mi))
hi = mi;
else
lo = mi;
}
printf("%d\n", hi);
} int main()
{
scanf("%d%d%d", &K, &C, &M);
V = K + C;
for (int i = 0; i < V; i++)
{
for (int j = 0; j < V; j++)
{
int d;
scanf("%d", &d);
D[i][j] = d ? d : INF;
}
}
solve(); return 0;
}

POJ2112题解的更多相关文章

  1. POJ2112 Optimal Milking —— 二分图多重匹配/最大流 + 二分

    题目链接:https://vjudge.net/problem/POJ-2112 Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K T ...

  2. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  3. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  4. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  5. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  6. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  7. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  8. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  9. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

随机推荐

  1. 集合框架-HashSet集合(无序唯一)

    1 package cn.itcast.p4.hashset.demo; 2 3 import java.util.HashSet; 4 import java.util.Iterator; 5 /* ...

  2. ORACLE数据库误操作DELETE并且提交数据库之后如何恢复被删除的数据

    一:根据时间来恢复: 1.查询数据库当前时间() select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual; 2.查询删除数据时间点之前的数据 ...

  3. %r和%s的区别

    理解%r和%s的区别 %r会重现所表达的对象,%s会将所有转成字符串 eg1: print('i am %s years old' % 22) print('i am %r years old' % ...

  4. keystore文件

    [-] keystore操作 运行时签名文件路径debug 生成签名文件打包时使用 获取MD5和SH1 修改keystore文件密码 修改keystore文件别名 修改keystore文件别名的密码 ...

  5. 接口里的default,static方法

    我们都知道接口里的变量默认隐含类型是public static final,也是就是说是常量.而方法默认类型是public abstract,所以接口的方法都是抽象方法,但是事实真的是这样吗? 我的P ...

  6. NSLog输出格式及随机数

    NSLog输出格式及随机数 %@ 对象 %d, %i 整数 (%i和%d无差别,%i是老式写法,%d是新式写法而已.) %u 无符整形 %f 浮点/双字 %x, %X 二进制整数 %o 八进制整数 % ...

  7. memcache启动多个服务

    windows 7 64bit 环境下安装memcached 1.下载后解压到D:\memcached(下载地址:memcached-win64下载地址) 2.安装到windows服务,打开cmd命令 ...

  8. 关于LVS的问题总结

    关于LVS的问题总结 目录 关于LVS的问题总结 1. LVS工作模式及区别 2. LVS调度算法 3. LVS调度器你的常用算法(均衡策略) (1)固定调度算法:rr.wrr.dh.sh (2)动态 ...

  9. SpringBoot源码解读系列——开篇

    什么是SpringBoot? 定义可以参考官网:SpringBoot官网,其定义通俗易懂,这里就不赘述. 官网也给出了一个通用的SpringBoot工程样例,其中包含了这么几个元素: 1.pom依赖 ...

  10. .netcore基础知识(一)

    先来说说web服务器  先来一张图 一个典型的进程外托管模型 我们先看kestrel这一部分 我们在它前面放了一个方向代理服务器nginx 对http请求做预处理 kestrel本身是可以直接用作we ...