题目链接:https://vjudge.net/problem/POJ-2112

Optimal Milking
Time Limit: 2000MS   Memory Limit: 30000K
Total Submissions: 18555   Accepted: 6626
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

题解:

题意:有n头牛, m个挤奶器(只能为个数限定的牛挤奶)。每头牛和挤奶器都有其固定的位置。主人安排每头牛去某个挤奶器中挤奶,且在途中,牛可以经过其他地方。为了节省牛的体力,主人希望路途最长的那头牛的路途尽可能短(最大值最小)。

1.用Floyd算法求出每头牛到每个挤奶器的最短路径。

2.二分最长路径,然后重新建图,如果某条路径的长度小于等于最长路径,则连起两端点;否则,两端点没有连接。

3.利用二分图多重匹配或者最大流,求出是否每头牛都能在某台挤奶器中挤奶。如果可以,则减小最长路径;否则增大最长路径。

多重匹配:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <sstream>
#include <algorithm>
using namespace std;
const int INF = 2e9;
const int MOD = 1e9+;
const int MAXM = 5e2+;
const int MAXN = 4e2+; int uN, vN, m, N, maze[MAXN][MAXN];
int num[MAXM], linker[MAXM][MAXN];
bool g[MAXN][MAXM], used[MAXM]; bool dfs(int u)
{
for(int v = ; v<=vN; v++)
if(g[u][v] && !used[v])
{
used[v] = true;
if(linker[v][]<num[v])
{
linker[v][++linker[v][]] = u;
return true;
}
for(int i = ; i<=num[v]; i++)
if(dfs(linker[v][i]))
{
linker[v][i] = u;
return true;
}
}
return false;
} bool hungary(int mid)
{
memset(g, false, sizeof(g));
for(int i = vN+; i<=N; i++)
for(int j = ; j<=vN; j++)
if(maze[i][j]<=mid)
g[i][j] = true; for(int i = ; i<=vN; i++)
{
num[i] = m;
linker[i][] = ;
}
for(int u = vN+; u<=N; u++)
{
memset(used, false, sizeof(used));
if(!dfs(u)) return false;
}
return true;
} void Flyod()
{
for(int k = ; k<=N; k++)
for(int i = ; i<=N; i++)
for(int j = ; j<=N; j++)
maze[i][j] = min(maze[i][j], maze[i][k]+maze[k][j]);
} int main()
{
while(scanf("%d%d%d", &vN, &uN, &m)!=EOF)
{
N = uN + vN;
for(int i = ; i<=N; i++)
for(int j = ; j<=N; j++)
{
scanf("%d", &maze[i][j]);
if(maze[i][j]==) maze[i][j] = INF/;
} Flyod();
int l = , r = *;
while(l<=r)
{
int mid = (l+r)>>;
if(hungary(mid))
r = mid - ;
else
l = mid + ;
}
printf("%d\n", l);
}
}

最大流:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <sstream>
#include <algorithm>
using namespace std;
const int INF = 2e9;
const int MOD = 1e9+;
const int MAXM = 5e2+;
const int MAXN = 4e2+; struct Edge
{
int to, next, cap, flow;
}edge[MAXN*MAXN];
int tot, head[MAXN]; int uN, vN, m, N, maze[MAXN][MAXN];
int gap[MAXN], dep[MAXN], pre[MAXN], cur[MAXN];
void add(int u, int v, int w)
{
edge[tot].to = v; edge[tot].cap = w; edge[tot].flow = ;
edge[tot].next = head[u]; head[u] = tot++;
edge[tot].to = u; edge[tot].cap = ; edge[tot].flow = ;
edge[tot].next = head[v]; head[v] = tot++;
} int sap(int start, int end, int nodenum)
{
memset(dep, , sizeof(dep));
memset(gap, , sizeof(gap));
memcpy(cur, head, sizeof(head));
int u = pre[start] = start, maxflow = ,aug = INF;
gap[] = nodenum;
while(dep[start]<nodenum)
{
loop:
for(int i = cur[u]; i!=-; i = edge[i].next)
{
int v = edge[i].to;
if(edge[i].cap-edge[i].flow && dep[u]==dep[v]+)
{
aug = min(aug, edge[i].cap-edge[i].flow);
pre[v] = u;
cur[u] = i;
u = v;
if(v==end)
{
maxflow += aug;
for(u = pre[u]; v!=start; v = u,u = pre[u])
{
edge[cur[u]].flow += aug;
edge[cur[u]^].flow -= aug;
}
aug = INF;
}
goto loop;
}
}
int mindis = nodenum;
for(int i = head[u]; i!=-; i = edge[i].next)
{
int v=edge[i].to;
if(edge[i].cap-edge[i].flow && mindis>dep[v])
{
cur[u] = i;
mindis = dep[v];
}
}
if((--gap[dep[u]])==)break;
gap[dep[u]=mindis+]++;
u = pre[u];
}
return maxflow;
} bool test(int mid)
{
tot = ;
memset(head, -, sizeof(head));
for(int i = vN+; i<=N; i++)
{
add(, i, );
for(int j = ; j<=vN; j++)
if(maze[i][j]<=mid)
add(i, j, );
}
for(int i = ; i<=vN; i++)
add(i, N+, m); int maxflow = sap(, N+, N+);
return maxflow == uN;
} void Flyod()
{
for(int k = ; k<=N; k++)
for(int i = ; i<=N; i++)
for(int j = ; j<=N; j++)
maze[i][j] = min(maze[i][j], maze[i][k]+maze[k][j]);
} int main()
{
while(scanf("%d%d%d", &vN, &uN, &m)!=EOF)
{
N = uN + vN;
for(int i = ; i<=N; i++)
for(int j = ; j<=N; j++)
{
scanf("%d", &maze[i][j]);
if(maze[i][j]==) maze[i][j] = INF/;
} Flyod();
int l = , r = *;
while(l<=r)
{
int mid = (l+r)>>;
if(test(mid))
r = mid - ;
else
l = mid + ;
}
printf("%d\n", l);
}
}

最新文章

  1. Python 实现Windows开机运行某软件
  2. C#设计模式系列:工厂方法模式(Factory Method)
  3. C#的一维数组和二维数组定义方式:
  4. Python 类变量和成员变量
  5. yacc和lex在ubuntu上安装
  6. 重新想象 Windows 8.1 Store Apps (81) - 控件增强: 加载本地 html, 智能替换 html 中的 url 引用, 通过 Share Contract 分享 WebView 中的内容, 为 WebView 截图
  7. WPF 简易的跑马灯效果
  8. Hadoop之Hive篇
  9. 关于Unity的协程
  10. C程序设计-----第1次作业
  11. Linux Centos7.x 安装部署Mysql5.7几种方式的操作手册
  12. postgresql 空间函数 随笔
  13. HDU 1027(数字排列 STL)
  14. vue-cli3.0 升级记录
  15. eclipse中安装windowbuilder插件、应用及卸载
  16. 列表与if语句的结合
  17. 用上了Godaddy的美国主机
  18. Unity 2D相机公式换算(从其他博客上抄的)
  19. Androidの疑难杂症之加载布局报Error inflating class &lt;unknown&gt;
  20. ansible 删除路径下的多个文件[收集的参考]

热门文章

  1. Python+selenium常用方法(Webdriver API)
  2. (3)梯度下降法Gradient Descent
  3. hexo干货系列:(四)将hexo博客同时托管到github和coding
  4. MyBatis使用Mapper动态代理开发Dao层
  5. 洛谷P1077 摆花
  6. 没有上司的舞会(hdu 1520)
  7. HTTP错误:java.lang.IllegalArgumentException: Illegal character in scheme at index 0: http://xxxxxx
  8. linux命令2——进程相关
  9. Flex4分模块下样式动态加载步骤及相关问题的解决
  10. Linux审计sudo