POJ2112 Optimal Milking —— 二分图多重匹配/最大流 + 二分
题目链接:https://vjudge.net/problem/POJ-2112
Time Limit: 2000MS | Memory Limit: 30000K | |
Total Submissions: 18555 | Accepted: 6626 | |
Case Time Limit: 1000MS |
Description
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
* 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
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);
}
}
POJ2112 Optimal Milking —— 二分图多重匹配/最大流 + 二分的更多相关文章
- POJ3189 Steady Cow Assignment —— 二分图多重匹配/最大流 + 二分
题目链接:https://vjudge.net/problem/POJ-3189 Steady Cow Assignment Time Limit: 1000MS Memory Limit: 65 ...
- POJ2289 Jamie's Contact Groups —— 二分图多重匹配/最大流 + 二分
题目链接:https://vjudge.net/problem/POJ-2289 Jamie's Contact Groups Time Limit: 7000MS Memory Limit: 6 ...
- hdu3605 Escape 二分图多重匹配/最大流
2012 If this is the end of the world how to do? I do not know how. But now scientists have found tha ...
- POJ 2112—— Optimal Milking——————【多重匹配、二分枚举答案、floyd预处理】
Optimal Milking Time Limit:2000MS Memory Limit:30000KB 64bit IO Format:%I64d & %I64u Sub ...
- POJ2112 Optimal Milking
Optimal Milking Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 17811 Accepted: 6368 ...
- Poj 2289 Jamie's Contact Groups (二分+二分图多重匹配)
题目链接: Poj 2289 Jamie's Contact Groups 题目描述: 给出n个人的名单和每个人可以被分到的组,问将n个人分到m个组内,并且人数最多的组人数要尽量少,问人数最多的组有多 ...
- POJ2112:Optimal Milking(Floyd+二分图多重匹配+二分)
Optimal Milking Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 20262 Accepted: 7230 ...
- 【网络流24题】No.7 试题库问题 (最大流,二分图多重匹配)
[题意] 假设一个试题库中有 n 道试题. 每道试题都标明了所属类别. 同一道题可能有多个类别属性.现要从题库中抽取 m 道题组成试卷.并要求试卷包含指定类型的试题. 试设计一个满足要求的组卷算法. ...
- 网络流24题 第五题 - PowerOJ1740 CodeVS1905 圆桌问题 二分图多重匹配 网络最大流
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - PowerOJ1740 - 有SPJ - 推荐 题目传送门 - CodeVS1905 - 无SPJ - 0% ...
随机推荐
- 1. node.js环境搭建 第一行代码
一.NodeJs简介 NodeJS官网上的介绍: Node.js is a platform built on Chrome's JavaScript runtime for easily bui ...
- luogu4093 [HEOI2016/TJOI2016]序列
因为一个变化只会变化一个值,所以 \(dp[i]=max(dp[j])+1,j<i,maxval_j \leq a[i], a[j] \leq minval_i\) 发现跟二维数点问题挺像,树状 ...
- Selenium加载Chrome/Firefox浏览器配置文件
Selenium启动浏览器时,默认是打开一个新用户,不会加载原有的配置以及插件.但有些时候我们可能需要加载默认配置. 一.Chrome浏览器 1.在Chrome浏览器的地址栏输入:chrome://v ...
- zoj 2109 FatMouse' Trade
FatMouse' Trade Time Limit: 2 Seconds Memory Limit: 65536 KB FatMouse prepared M pounds of cat ...
- vi/vim复制粘贴命令
1. 选定文本块.使用v进入可视模式,移动光标键选定内容. 2.复制的命令是y,即yank(提起) ,常用的命令如下: y 在使用v模式选定了某一块的时候,复制选定块到缓冲区用: ...
- python(4)- 字符编码
一 什么是编码? 基本概念很简单.首先,我们从一段信息即消息说起,消息以人类可以理解.易懂的表示存在.我打算将这种表示称为“明文”(plain text).对于说英语的人,纸张上打印的或屏幕上显示的英 ...
- HDU 6333 莫队+组合数
Problem B. Harvest of Apples Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K ...
- HDU——2768 Cat vs. Dog
Cat vs. Dog Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- Linux中查看文件或者文件夹大小
df -l 查看磁盘空间大小命令 df -hl 查看磁盘剩余空间 df -h 查看每个根路径的分区大小 du -sh 当前文件夹下所有文件大小(包括子文件大小 du -sm [文件夹] 返回该 ...
- VMware虚拟机上安装linux和克隆
虚拟机上安装好一台linux 系统后.为了高速搭建hadoop集群.须要再安装几个linux系统,比較笨的办法能够又一次用ios 镜像文件进行安装.可是又一次安装须要又一次配置一些信息并且安装时间比較 ...