Optimal Milking
Time Limit: 2000MS   Memory Limit: 30000K
Total Submissions: 15682   Accepted: 5597
Case Time Limit: 1000MS

Description

FJ has moved his K (1 <= K <= 30) milking machines out into the cow pastures among the C (1 <= C <= 200) cows. A set of paths of various lengths runs among the cows and the milking machines. The milking machine locations are named by ID numbers 1..K; the cow locations are named by ID numbers K+1..K+C.

Each milking point can "process" at most M (1 <= M <= 15) cows each day.

Write a program to find an assignment for each cow to some milking machine so that the distance the furthest-walking cow travels is minimized (and, of course, the milking machines are not overutilized). At least one legal assignment is possible for all input data sets. Cows can traverse several paths on the way to their milking machine.

Input

* Line 1: A single line with three space-separated integers: K, C, and M.

* Lines 2.. ...: Each of these K+C lines of K+C space-separated integers describes the distances between pairs of various entities. The input forms a symmetric matrix. Line 2 tells the distances from milking machine 1 to each of the other entities; line 3 tells the distances from machine 2 to each of the other entities, and so on. Distances of entities directly connected by a path are positive integers no larger than 200. Entities not directly connected by a path have a distance of 0. The distance from an entity to itself (i.e., all numbers on the diagonal) is also given as 0. To keep the input lines of reasonable length, when K+C > 15, a row is broken into successive lines of 15 numbers and a potentially shorter line to finish up a row. Each new row begins on its own line.

Output

A single line with a single integer that is the minimum possible total distance for the furthest walking cow. 

Sample Input

2 3 2
0 3 2 1 1
3 0 3 2 0
2 3 0 1 0
1 2 1 0 2
1 0 0 2 0

Sample Output

2

Source

2112题意:给出K+C个点,前K个点代表牛棚,之后的C个点代表牛,所有的牛都要转移到牛棚中去,然而每个牛棚最多能容纳M头牛,问最短多长时间可以将所有牛转移到牛棚中去(每条边不限制同一时间通过数量,牛可以同时移动)。输入数据第一行三个整数K C M,接下来一个邻接矩阵D,D[i][j]表示点i到点j的距离,D[i][i] = 0,当i!=j时D[i][j] == 0表示i与j之间没有直接的路径。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <algorithm>
#include <set>
using namespace std;
#define MM(a,b) memset(a,b,sizeof(a))
typedef long long ll;
typedef unsigned long long ULL;
const int mod = 1000000007;
const double eps = 1e-10;
const int inf = 0x3f3f3f3f;
const int big=50000;
int max(int a,int b) {return a>b?a:b;};
int min(int a,int b) {return a<b?a:b;};
struct edge{
int to,cap,rev;
};
vector<edge> G[250];
int tol,k,c,m,level[250],iter[250],mp[250][250]; void add_edge(int u,int v,int cap)
{
G[u].push_back(edge{v,cap,G[v].size()});
G[v].push_back(edge{u,0,G[u].size()-1});
} void bfs(int s)
{
queue<int> q;
q.push(s);
level[s]=1;
while(q.size())
{
int now=q.front();q.pop();
for(int i=0;i<G[now].size();i++)
if(G[now][i].cap>0)
{
edge e=G[now][i];
if(level[e.to]<0)
{
level[e.to]=level[now]+1;
q.push(e.to);
}
}
}
}
int dfs(int s,int t,int minn)
{
if(s==t)
return minn;
for(int &i=iter[s];i<G[s].size();i++)
{
edge &e=G[s][i];
if(level[e.to]>level[s]&&e.cap>0)
{
int k=dfs(e.to,t,min(minn,e.cap));
if(k>0)
{
e.cap-=k;
G[e.to][e.rev].cap+=k;
return k;
}
}
}
return 0;
} int max_flow(int s,int t)
{
int ans=0,temp;
for(;;)
{
memset(level,-1,sizeof(level));
bfs(s);
if(level[t]<0)
return ans;
memset(iter,0,sizeof(iter));
while((temp=dfs(s,t,inf))>0)
ans+=temp;
}
return ans;
} void buildgraph(int mid)
{
for(int i=0;i<=tol+1;i++) G[i].clear(); for(int i=1;i<=k;i++)
add_edge(0,i,m); for(int i=1;i<=k;i++)
for(int j=k+1;j<=k+c;j++)
if(mp[i][j]<=mid)
add_edge(i,j,1); for(int j=k+1;j<=k+c;j++)
add_edge(j,tol+1,1);
} void floyd()
{
for(int k=1;k<=tol;k++)
for(int i=1;i<=tol;i++)
for(int j=1;j<=tol;j++)
mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]); } int main()
{
while(~scanf("%d %d %d",&k,&c,&m))
{
tol=k+c;
MM(mp,inf);
for(int i=1;i<=tol;i++)
for(int j=1;j<=tol;j++)
{
int w;
scanf("%d",&w);
if(!w&&(i!=j)) w=inf;
mp[i][j]=w;
} floyd(); int l=-1,r=200*55;
while(r-l>1)
{
int mid=(l+r)>>1;
buildgraph(mid);
if(max_flow(0,tol+1)>=c) r=mid;
else l=mid;
}
printf("%d\n",r);
}
return 0;
}

  分析:很经典的一道题,

1.因为要最小化最大长度,所以想到了二分;

2.利用Floyd求出任意两点之间的距离

2.二分出一个mid值后,重新建图,对于奶牛与机器之间距离<=mid的建立一条容量为1的边,否则不建边,最后看最大流跑出来的数值是否是==牛的个数的,如果是,则说明该mid是合法的,反之亦然。

TTTTTTTTTTTT POJ 2112 奶牛与机器 多重二分匹配 跑最大流 建图很经典!!的更多相关文章

  1. [poj 3281]最大流+建图很巧妙

    题目链接:http://poj.org/problem?id=3281 看了kuangbin大佬的思路,还用着kuangbin板子orz   http://www.cnblogs.com/kuangb ...

  2. poj 3281 最大流+建图

    很巧妙的思想 转自:http://www.cnblogs.com/kuangbin/archive/2012/08/21/2649850.html 本题能够想到用最大流做,那真的是太绝了.建模的方法很 ...

  3. POJ 2112—— Optimal Milking——————【多重匹配、二分枚举答案、floyd预处理】

    Optimal Milking Time Limit:2000MS     Memory Limit:30000KB     64bit IO Format:%I64d & %I64u Sub ...

  4. 图论--网络流--最大流 POJ 2289 Jamie's Contact Groups (二分+限流建图)

    Description Jamie is a very popular girl and has quite a lot of friends, so she always keeps a very ...

  5. poj 3281 Dining 网络流-最大流-建图的题

    题意很简单:JOHN是一个农场主养了一些奶牛,神奇的是这些个奶牛有不同的品味,只喜欢吃某些食物,喝某些饮料,傻傻的John做了很多食物和饮料,但她不知道可以最多喂饱多少牛,(喂饱当然是有吃有喝才会饱) ...

  6. poj 1149 Pigs 网络流-最大流 建图的题目(明天更新)-已更新

    题目大意:是有M个猪圈,N个顾客,顾客要买猪,神奇的是顾客有一些猪圈的钥匙而主人MIRKO却没有钥匙,多么神奇?顾客可以在打开的猪圈购买任意数量的猪,只要猪圈里有足够数量的猪.而且当顾客打开猪圈后mi ...

  7. Antenna Placement POJ - 3020 二分图匹配 匈牙利 拆点建图 最小路径覆盖

    题意:图没什么用  给出一个地图 地图上有 点 一次可以覆盖2个连续 的点( 左右 或者 上下表示连续)问最少几条边可以使得每个点都被覆盖 最小路径覆盖       最小路径覆盖=|G|-最大匹配数 ...

  8. D唐纳德和他的数学老师(华师网络赛)(二分匹配,最大流)

    Time limit per test: 1.0 seconds Memory limit: 256 megabytes 唐纳德是一个数学天才.有一天,他的数学老师决定为难一下他.他跟唐纳德说:「现在 ...

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

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

随机推荐

  1. kafka整理笔记笔记

    一.为什么需要消息系统 解耦: 允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束. 冗余: 消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险.许多消息 ...

  2. 解决Sublime Text3中文符号以及中文显示乱码问题

    今天安装了sublime Text3,发现中文符号显示是乱码,刚开始以为是编码问题,经过各种尝试,终于找到了解决办法.解决方法如下: 一.安装包管理器 使用Ctrl+~快捷键或者通过View-> ...

  3. Windows Runtime (RT)

    学了sl for wp 开发了1年都没入门,只能说自己的学习欲望太低了. 今天偶然才发现wrt 跟 .net 是2个东西... orz. 得抛弃 sl ,wrt才是未来的主流吧... 这篇文章不错 h ...

  4. Codeforces 1221F. Choose a Square

    传送门 对于某个点 $(x,y)$ ,不妨设 $x<y$ 因为如果 $x>y$ 直接按 $y=x$ 对称一下即可 当且仅当正方形左下角 $(a,a)$ 满足 $a<=x$,右上角 $ ...

  5. 从0开始入门ssm-crm系统实战

    喜欢就点个赞呗! GitHub项目ssm-learn-crm show me the code and take to me,做的出来更要说的明白 1.1 克隆 git clone https://g ...

  6. TKmybatis和mybatisplus哪个好用

    文档连接 :http://baomidou.oschina.io/mybatis-plus-doc/#/?id=%E7%AE%80%E4%BB%8B https://gitee.com/hengboy ...

  7. Caffe中im2col的实现解析

    这里,我是将Caffe中im2col的解析过程直接拉了出来,使用C++进行了输出,方便理解.代码如下: #include<iostream> using namespace std; bo ...

  8. 给定一个字符串,根据字符出现频率排序--Java实现

    题目描述: 给定一个字符串,请将字符串里的字符按照出现的频率降序排列. 示例 1: 输入:"tree" 输出:"eert" 解释:'e'出现两次,'r'和't' ...

  9. python将str类型的数据变成datetime时间类型数据

    如下: import datetime date_str = '2019_05_09' date_date = datetime.date(*map(int, date_str.split('_')) ...

  10. Java语言基础(4)

    1 关系运算符:>,>=,<,<=,==,!= 案例:Demo1 public class Demo1 { //偶数:能被2整除的整数 //2,4,6,8,10... //整除 ...