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% ...
随机推荐
- LA 4064 (计数 极角排序) Magnetic Train Tracks
这个题和UVa11529很相似. 枚举一个中心点,然后按极角排序,统计以这个点为钝角的三角形的个数,然后用C(n, 3)减去就是答案. 另外遇到直角三角形的情况很是蛋疼,可以用一个eps,不嫌麻烦的话 ...
- jenkins 提示No emails were triggered
发送邮件 Jenkins->系统管理->系统设置,在“邮件通知”里设置smtp服务器地址,以及发送者邮箱地址,在具体的任务构建完成以后,可以设置发送邮件,在某一个任务的"Add ...
- 一、SQL基础知识点补充
SQL DML 和 DDL 可以把 SQL 分为两个部分:数据操作语言 (DML) 和 数据定义语言 (DDL). SQL (结构化查询语言)是用于执行查询的语法.但是 SQL 语言也包含用于更新.插 ...
- [luoguP1273] 有线电视网(DP)
传送门 f[i][j]表示节点i选j个用户的最大收益 #include <cstdio> #include <cstring> #include <iostream> ...
- 【构造+DFS】2017多校训练三 HDU 6060 RXD and dividing
acm.hdu.edu.cn/showproblem.php?pid=6060 [题意] 给定一棵以1为根的树,把这颗树除1以外的结点划分为k个集合(可以有空集),把1加入划分后的集合 每个集合的结点 ...
- To_Date函数用法
spl> select * from emp where dates between to_date('2007-06-12 10:00:0 ...
- ascii 和 byte以及UTF-8的转码规则
多年来闲麻烦,只记录笔记,不曾编写BLOG,本文为原创,如需转载请标明出处 废话不说,直奔主题 ascii 计算机只接受 “高”.“低”电压,所以使用二进制 1 和 0 分别代表高低电压 ...
- 1716: [Usaco2006 Dec]The Fewest Coins 找零钱
n<=100种硬币,给每种的硬币的面额<=120和我每种有多少个<=10000,店主的硬币跟我一样但有无限个,求买t<=10000块钱的东西钱最少转手几次. 我拿的硬币最少几次 ...
- 洛谷——P2068 统计和
P2068 统计和 题目描述 给定一个长度为n(n<=100000),初始值都为0的序列,x(x<=10000)次的修改某些位置上的数字,每次加上一个数,然后提出y (y<=1000 ...
- poj——1274 The Perfect Stall
poj——1274 The Perfect Stall Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 25709 A ...