POJ--2112--Optimal Milking【Floyd+Dinic+二分答案】

链接:http://poj.org/problem?id=2112

题意:有k个挤奶器,编号1~k,c头牛,编号k+1~k+c,每个挤奶器最多能给m头牛挤奶,给你一个k+c的邻接矩阵,要求每头牛都能挤奶并且要求c头牛需要走的所有路程中的最大路程最小,求这个最小的路。

思路:

1. 先用floyd处理出多源最短路

2. 用二分枚举答案的可能,初始上限应该为(200+30)*200,但是我这么开T了,可能因为代码太挫,改到1000,卡着时间过了,只能说poj数据弱了。后来看别人的代码,和我的做法一样但是用了邻接表,就能设上限为40000了。在二分中:

(1)构造容量网络,以0点为源点,到每头牛的容量为1,以n+1点为汇点,每个挤奶器到汇点的容量为m,当然反过来也可以,因为源点和汇点的流量是相等的(等于c)。对于每头牛和每个挤奶器之间的距离,如果比枚举的距离还大,则容量为0,否则容量为1。

(2)Dinic找出网络最大流,很明显最大流最大是c,当最大流是c的时候是一种答案,但不一定是最优,更新二分上限,如果最大流没达到c,则更新下限。

#include<cstring>
#include<string>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<ctime>
#include<cstdlib>
#include<functional>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define MAXN 50100
#define eps 1e-7
#define INF 0x7FFFFFFF
#define seed 131
#define mod 1000000007
#define ll long long
#define ull unsigned ll
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

int edge[300][300],customer[300][300];
int vis[300],dist[300][300];
int n,m,k,c;
void floyd(){
    int i,j,k;
    for(k=1;k<=n;k++){
        for(i=1;i<=n;i++){
            for(j=1;j<=n;j++){
                if(edge[i][k]!=INF&&edge[k][j]!=INF&&edge[i][k]+edge[k][j]<edge[i][j])
                    edge[i][j] = edge[i][k] + edge[k][j];
            }
        }
    }
}
void build_graph(int minm){
    int i,j;
    memset(customer,0,sizeof(customer));
    for(i=1;i<=k;i++)   customer[i][n+1] = m;
    for(i=k+1;i<=n;i++) customer[0][i] = 1;
    for(i=k+1;i<=n;i++){
        for(j=1;j<=k;j++){
            if(edge[i][j]<=minm) customer[i][j] = 1;
        }
    }
}
int bfs(){
    int i,j;
    memset(vis,0,sizeof(vis));
    memset(dist,0,sizeof(dist));
    queue<int>q;
    q.push(0);
    vis[0] = 1;
    while(!q.empty()){
        int t = q.front();
        q.pop();
        for(i=0;i<=n+1;i++){
            if(!vis[i]&&customer[t][i]){
                vis[i] = 1;
                dist[t][i] = 1;
                q.push(i);
            }
        }
    }
    if(vis[n+1])    return 1;
    else    return 0;
}
int dfs(int u,int delta){
    int i,j,s;
    if(u==n+1)  return delta;
    s = delta;
    for(i=0;i<=n+1;i++){
        if(dist[u][i]){
            int dd = dfs(i,min(customer[u][i],delta));
            customer[u][i] -= dd;
            customer[i][u] += dd;
            delta -= dd;
        }
    }
    return s - delta;
}
int main(){
    int i,j;
    while(scanf("%d%d%d",&k,&c,&m)!=EOF){
        n = k + c;
        for(i=1;i<=n;i++){
            for(j=1;j<=n;j++){
                scanf("%d",&edge[i][j]);
                if(edge[i][j]==0)   edge[i][j] = INF;
            }
        }
        floyd();
        int mid, l = 0, r = 10000;
        int sum;
        while(l<r){
            mid = (l+r)/2;
            sum = 0;
            build_graph(mid);
            while(bfs())    sum += dfs(0,INF);
            if(sum==c)  r = mid;
            else    l = mid + 1;
        }
        printf("%d\n",l);
    }
    return 0;
}

POJ--2112--Optimal Milking【Floyd+Dinic+二分答案】

时间: 2025-01-11 21:58:55

POJ--2112--Optimal Milking【Floyd+Dinic+二分答案】的相关文章

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 最优挤奶方案 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 (二分 + 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(二分+最大流)

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 (二分 + 最大流)

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

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

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

poj 2112 Optimal Milking (二分图匹配的多重匹配)

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