POJ 2112 Optimal Milking(最大流)
2015-07-19 10:16
295 查看
题目链接:http://poj.org/problem?id=2112
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
Sample Output
Source
USACO 2003 U S Open
题目描述:(转)
k个机器,每个机器最多服务m头牛。
c头牛,每个牛需要1台机器来服务。
告诉你牛与机器每个之间的直接距离。
问:让所有的牛都被服务的情况下,使走的最远的牛的距离最短,求这个距离。
解题报告:
二分枚举距离,实际距离满足当前枚举距离限制的可以加入这条边。枚举的距离中符合条件的最小值就是答案。
建图过程:
一个超级原点,和每个机器的容量都是m。
一个超级汇点,每头牛和汇点的容量都是1.
机器i与牛j之间的距离如果小于等于当前枚举值mid,连接i,j,容量1.
这样最大流的意义就是能够服务的牛最多是多少,如果最大流等于牛的总数c,表示当前枚举值mid符合条件,同时说明mid值还可能可以更小,更新二分右边界r = mid - 1.
如果小于牛的总数,说明mid偏小,更新二分左边界,l = mid + 1.
机器与牛之间的最短距离可以用floyd预处理出来。
代码如下:
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
USACO 2003 U S Open
题目描述:(转)
k个机器,每个机器最多服务m头牛。
c头牛,每个牛需要1台机器来服务。
告诉你牛与机器每个之间的直接距离。
问:让所有的牛都被服务的情况下,使走的最远的牛的距离最短,求这个距离。
解题报告:
二分枚举距离,实际距离满足当前枚举距离限制的可以加入这条边。枚举的距离中符合条件的最小值就是答案。
建图过程:
一个超级原点,和每个机器的容量都是m。
一个超级汇点,每头牛和汇点的容量都是1.
机器i与牛j之间的距离如果小于等于当前枚举值mid,连接i,j,容量1.
这样最大流的意义就是能够服务的牛最多是多少,如果最大流等于牛的总数c,表示当前枚举值mid符合条件,同时说明mid值还可能可以更小,更新二分右边界r = mid - 1.
如果小于牛的总数,说明mid偏小,更新二分左边界,l = mid + 1.
机器与牛之间的最短距离可以用floyd预处理出来。
代码如下:
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; const int MAXN = 310;//点数的最大值 const int MAXM = 40010;//边数的最大值 const int INF = 0x3f3f3f3f; struct Edge { int to,next,cap,flow; } edge[MAXM]; //注意是MAXM int tol; int head[MAXN]; int gap[MAXN],dep[MAXN],cur[MAXN]; int k, c, m; int s, e;//源点,汇点 int map[MAXN][MAXN]; int mid;//二分中间值; int num;//矩阵的规格; //加边,单向图三个参数,双向图四个参数 void addedge(int u,int v,int w,int rw = 0) { edge[tol].to = v; edge[tol].cap = w; edge[tol].flow = 0; edge[tol].next = head[u]; head[u] = tol++; edge[tol].to = u; edge[tol].cap = rw; edge[tol].flow = 0; edge[tol].next = head[v]; head[v] = tol++; } int Q[MAXN]; void BFS(int start,int end) { memset(dep,-1,sizeof(dep)); memset(gap,0,sizeof(gap)); gap[0] = 1; int front = 0, rear = 0; dep[end] = 0; Q[rear++] = end; while(front != rear) { int u = Q[front++]; for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if(dep[v] != -1)continue; Q[rear++] = v; dep[v] = dep[u] + 1; gap[dep[v]]++; } } } int S[MAXN]; //输入参数:起点、终点、点的总数 //点的编号没有影响,只要输入点的总数 int sap(int start,int end,int N) { BFS(start,end); memcpy(cur,head,sizeof(head)); int top = 0; int u = start; int ans = 0; while(dep[start] < N) { if(u == end) { int Min = INF; int inser; for(int i = 0; i < top; i++) if(Min > edge[S[i]].cap - edge[S[i]].flow) { Min = edge[S[i]].cap - edge[S[i]].flow; inser = i; } for(int i = 0; i < top; i++) { edge[S[i]].flow += Min; edge[S[i]^1].flow -= Min; } ans += Min; top = inser; u = edge[S[top]^1].to; continue; } bool flag = false; int v; for(int i = cur[u]; i != -1; i = edge[i].next) { v = edge[i].to; if(edge[i].cap - edge[i].flow && dep[v]+1 == dep[u]) { flag = true; cur[u] = i; break; } } if(flag) { S[top++] = cur[u]; u = v; continue; } int Min = N; for(int i = head[u]; i != -1; i = edge[i].next) if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min) { Min = dep[edge[i].to]; cur[u] = i; } gap[dep[u]]--; if(!gap[dep[u]])return ans; dep[u] = Min + 1; gap[dep[u]]++; if(u != start)u = edge[S[--top]^1].to; } return ans; } void Foyld()//两个点的最短距离 { for(int k = 1; k <= num; k++) { for(int i = 1; i <= num; i++) { for(int j = 1; j <= num; j++) { if(map[i][j] > map[i][k]+map[k][j]) { map[i][j] = map[i][k]+map[k][j]; } } } } } void init() { tol = 0; memset(head,-1,sizeof(head)); for(int i = 1; i <= k; i++)//k个挤奶器 { for(int j = k+1; j <= num; j++)//c头奶牛 { if(map[i][j] <= mid) { //如果奶牛到挤奶器的最短距离<=mid,建权值为1的边 addedge(j,i,1); } } } for(int i = 1; i <= k; i++) { addedge(i,e,m);//每个挤奶器最多可以挤k头牛 } for(int i = k+1; i <= num; i++) { addedge(s,i,1);//建一条源点到奶牛的边,权值为1 } } int main() { while(~scanf("%d%d%d",&k,&c,&m)) { num = k+c; s = 0;//源点 e = num+1;//汇点 int nv = num+2; //结点总数 for(int i = 1; i <= num; i++) { for(int j = 1; j <= num; j++) { scanf("%d",&map[i][j]); if(i!=j && !map[i][j]) { map[i][j] = INF; } } } Foyld(); int l = 0, r = INF; while(l <= r) { mid = (r+l)/2; init(); if(sap(s, e, nv) == c)//最大流等于c { r = mid-1; } else { l = mid+1; } } printf("%d\n",l); } return 0; }
相关文章推荐
- Hadoop--Hadoop2.X编译安装和实验------练习3
- php5.4.43开发环境的搭建(php5.4.43,apache2.2,mysql5.6以及phpMyAdmin)
- 嵌入式Linux module之符号导出
- Android Binder-涉及到Linux kernel相关知识点
- 在 CentOS 6.x上安装 docker.io成功
- linux下安装python
- 架构:层次化
- Shell编程中括号判断中赋值语句和判断语句
- jsoncpp在linux下的配置
- linux下添加用户并赋予root权限
- 嵌入式Linux模块的参数传递与多文件模块Makefile
- Linux内核里的“智能指针”
- 架构:一个软件框架必须符合如下要素
- linux文件基本操作(1)
- 架构师速成5.5-小学书单资料推荐
- 架构师速成5.5-小学书单资料推荐 分类: 架构师速成 2015-07-19 09:00 299人阅读 评论(0) 收藏
- vs2013下配置opencv3.0的问题
- 网站前台验证码(源代码)的实现点击刷新
- 《textanalytics》课程简单总结(2):topic mining
- linux小知识: ubuntu安装搜狗输入法