POJ 2112: Optimal Milking【二分,网络流】

题目大意:K台挤奶机,C个奶牛,每台挤奶器可以供M头牛使用,给出奶牛和和机器间的距离矩阵,求所有奶牛走最大距离的最小值

思路:最大距离的最小值,明显提示二分,将最小距离二分之后问题转化成为:K台挤奶机,C个奶牛,每台挤奶器可以供M头牛使用,已知每头牛可以到的挤奶机是哪些,问能否让所有奶牛挤上奶。

这个问题就是典型的二分图多重匹配问题,跑个网络流看是否满流即可,最后才发现给出的矩阵不一定是最短路径TUT 所以要跑一遍floyd

#include<iostream>

#include<cstdio>

#include <queue>

#include <string.h>

#define maxn 100000

#define inf 200000

using namespace std;

int head[maxn],point[maxn],next[maxn],flow[maxn];

int dis[maxn],now=0,dist[maxn];

int map[300][300],k,c,m,cop[maxn];

void floyd(int n){

for(int k=1;k<=n;k++)

for(int i=1;i<=n;i++)if(i!=k)

for(int j=1;j<=n;j++)if(j!=i && j!=k)

map[i][j]=min(map[i][j],map[i][k]+map[k][j]);

}

void add(int x,int y,int v,int vv){

next[++now]=head[x];head[x]=now;point[now]=y;flow[now]=v;

dis[now]=vv;next[++now]=head[y];head[y]=now;point[now]=x;flow[now]=0;dis[now]=vv;

}

int bfs(int s,int t,int x)

{

memset(dist,-1,sizeof(dist));

dist[s]=0;queue<int>q;q.push(s);

while(!q.empty())

{

int u=q.front();q.pop();

for(int i=head[u];i;i=next[i])

{

int k=point[i];

if(dist[k]==-1 && flow[i]!=0 && dis[i]<=x)

{

dist[k]=dist[u]+1;q.push(k);

}

}

}return dist[t]!=-1;

}

int dfs(int s,int d,int t,int x)

{

if(s==t)return d;int res=0;

for(int i=head[s];i&&res<d;i=next[i])

{

int u=point[i];

if(dist[u]==dist[s]+1 && flow[i]&& dis[i]<=x)

{

int dd=dfs(u,min(d-res,flow[i]),t,x);

if(dd){

flow[i]-=dd;flow[((i-1)^1)+1]+=dd;res+=dd;

}

}

}

if(res==0)dist[s]=-1;return res;

}

int judge(int x,int s,int t)

{

int ans=0;

while(bfs(s,t,x))ans+=dfs(s,inf,t,x);

memcpy(flow,cop,sizeof(flow));

if(ans==c)return 1;else return 0;

}

int main()

{

scanf("%d%d%d",&k,&c,&m);

int s=k+c+10,t=k+c+11,l=0,r=20000;

for(int i=1;i<=k+c;i++)

for(int j=1;j<=k+c;j++)

{

scanf("%d",&map[i][j]);if(map[i][j]==0)map[i][j]=inf;

}

floyd(k+c);

for(int i=k+1;i<=k+c;i++)

for(int j=1;j<=k;j++)

if(map[i][j]!=inf) add(i,j,1,map[i][j]);

for(int i=1;i<=k;i++)add(i,t,m,0);

for(int i=k+1;i<=k+c;i++)add(s,i,1,0);

memcpy(cop,flow,sizeof(flow));

while(l<r)

{

int mid=(l+r)>>1;

if(judge(mid,s,t))r=mid;else l=mid+1;

}

printf("%d\n",l);

return 0;

}

时间: 2024-11-14 12:43:11

POJ 2112: Optimal Milking【二分,网络流】的相关文章

POJ 2112 Optimal Milking 二分答案+最大流

首先二分最长的边,然后删去所有比当前枚举的值长的边,算最大流,看是否能满足所有的牛都能找到挤奶的地方 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include

POJ 2112 Optimal Milking (二分 + 最大流)

题目大意: 在一个农场里面,有k个挤奶机,编号分别是 1..k,有c头奶牛,编号分别是k+1 .. k+c,每个挤奶机一天最让可以挤m头奶牛的奶,奶牛和挤奶机之间用邻接矩阵给出距离.求让所有奶牛都挤到 奶的情况下,走的最远的那头奶牛走的距离最小是多少. 数据保证有解. 算法讨论: 首先可以想到是二分,然后在选择流网络的时候,一开始选择的最小费用最大流,让二分的边权充当最小费用,但是这样跑发现每次二分的是我们要跑的答案,不可行.所以就改用最大流. 最大流肯定是在二分的情况下判定最大流是否等于c,即

POJ 2112 Optimal Milking 【网络流】【二分】【最短路】

题意: k c m 分别代表挤奶机数量,牛数量,和挤奶机容量. 接下来(n=k+c)n*n的矩阵A,代表挤奶机或者牛的距离,如果对角线都为0,如果非对角线没有直接路相连也为0. 1 <= K <= 30  1 <= C <= 200  1 <= M <= 15  0<=Aij<=200 求:在机器不能过载工作的前提下,最远的牛到挤奶机的距离的最小值. 思路: 1.先跑一遍FLOYD求出任何两点的最短路. 2.二分最远的距离,从源点到1到k号点的边容量为m,然

POJ 2112 —— Optimal Milking 二分+Floyd+最大流

原题:http://poj.org/problem?id=2112 #include<cstdio> #include<cstring> #include<string> #include<queue> #include<vector> #include<algorithm> #define inf 0x3f3f3f3f using namespace std; const int maxn = 250; int dis[maxn][

POJ 2112 Optimal Milking (二分+最短路+最大流)

<题目链接> 题目大意: 有K台挤奶机和C头奶牛,都被视为物体,这K+C个物体之间存在路径.给出一个 (K+C)x(K+C) 的矩阵A,A[i][j]表示物体i和物体j之间的距离,有些物体之间可能没有直接通路. 每台挤奶机可以容纳m头奶牛去挤奶,且每个奶牛仅可以去往一台挤奶机.现在安排这C头奶牛去挤奶,每头奶牛会去往某个挤奶机,求出这C头奶牛去其挤奶的最长路径的最小值. 解题分析: 因为要求最长路径的最小值,所以我们很容易想到二分答案.由于数据量较小,所以我们先用floyed求出所有点之间的最

POJ 2112 Optimal Milking (二分 + floyd + 网络流)

POJ 2112 Optimal Milking 链接:http://poj.org/problem?id=2112 题意:农场主John 将他的K(1≤K≤30)个挤奶器运到牧场,在那里有C(1≤C≤200)头奶牛,在奶牛和挤奶器之间有一组不同长度的路.K个挤奶器的位置用1-K的编号标明,奶牛的位置用K+1-K+C 的编号标明.每台挤奶器每天最多能为M(1≤M≤15)头奶牛挤奶.寻找一个方案,安排每头奶牛到某个挤奶器挤奶,并使得C 头奶牛需要走的所有路程中的最大路程最小.每个测试数据中至少有一

POJ 2112 Optimal Milking 最优挤奶方案 Floyd算法+二分查找+最大流

题目链接:POJ 2112 Optimal Milking Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 12446   Accepted: 4494 Case Time Limit: 1000MS Description FJ has moved his K (1 <= K <= 30) milking machines out into the cow pastures among

POJ 2112 Optimal Milking(二分+最大流)

POJ 2112 Optimal Milking 题目链接 题意:给定一些机器和奶牛,在给定距离矩阵,(不在对角线上为0的值代表不可达),每个机器能容纳m个奶牛,问所有奶牛都能挤上奶,那么走的距离最大的奶牛的最小值是多少 思路:明显的二分+最大流,注意floyd求出的距离矩阵最大值可能不止200,所以二分的上限要注意 代码: #include <cstdio> #include <cstring> #include <queue> #include <algori

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

Optimal Milking Time Limit:2000MS     Memory Limit:30000KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2112 Description FJ has moved his K (1 <= K <= 30) milking machines out into the cow pastures among the C (1 <= C <= 20

POJ 2112 Optimal Milking

Optimal Milking Time Limit: 2000ms Memory Limit: 30000KB This problem will be judged on PKU. Original ID: 211264-bit integer IO format: %lld      Java class name: Main FJ has moved his K (1 <= K <= 30) milking machines out into the cow pastures amon