poj2112,最大流,最优挤奶方案

按图论列表上来说是基础题。

这道题是省赛之前过的,现在想再拿出来总结一下,感觉这个类型的题很经典。

题意不叙述了,就是有奶牛和机器,每台奶牛分配一个机器,

牛与牛、牛与机器、机器与机器之间都有一距离,求分配后的最大距离的最小值。

一开始没明白啥叫“最大距离的最小值”,就是C头奶牛、K个挤奶器,C头奶牛若想到全部的挤奶器那里去需要一定的距离,

C头奶牛当中某一头奶牛需要走的距离最大那这个距离便为最大值,要使这个最大值最小。(DT的题意)

这样子二分就好了,(又是二分,泥垢了),若根据mid建图后的最大流>=C,那这个便是成功的。

有一堆点位于X,一堆点位于Y,若试着建立从X到Y的某种关系,(比如距离、权值),加入超级源点与汇点S、T并建立相应权的边后

肯定能够使得X的点和Y的点分别属于集合S、T(这也是最小割的思想)。

ps:二分输出的技巧如我的代码  if(ans>=mid)  R = mid; cout<<R<<endl;  这样输出的R便是正确的了。

废话了比较多,仅是自己身为一个弱渣的小提醒。附个代码。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

const int INF = 0x3c3c3c3c;

const int maxn = 500 + 10; //结点最多数目
struct Edge{ //代表一条from->to容量为cap,流量为flow的弧
    int from, to, cap, flow;
};

struct Dinic{
    int n, m, s, t;   //结点数,边数(包括反向弧), 源点、汇点号
    vector<Edge> edges; //边表  edge[e]与edge[e^1]互为反向弧
    vector<int> G[maxn];
    bool vis[maxn];
    int d[maxn];
    int cur[maxn];

    void AddEdge(int from, int to, int cap){
        edges.push_back((Edge){from, to, cap, 0});
        edges.push_back((Edge){to, from, 0, 0});
        int m = edges.size();
        G[from].push_back(m-2);
        G[to].push_back(m-1);
    }

    bool BFS(){
        memset(vis, 0, sizeof(vis));
        queue<int> Q;
        Q.push(s);
        d[s] = 0;
        vis[s] = 1;
        while(!Q.empty()){
            int x = Q.front();  Q.pop();
            for(int i = 0;i < G[x].size();i++){
                Edge& e = edges[G[x][i]];
                if(!vis[e.to] && e.cap>e.flow){
                    vis[e.to] = 1;
                    d[e.to] = d[x] + 1;
                    Q.push(e.to);
                }
            }
        }
        return vis[t];
    }

    int DFS(int x, int a){
        if(x==t || a==0)  return a;
        int flow = 0, f;
        for(int &i = cur[x];i < G[x].size();i++){
            Edge& e = edges[G[x][i]];
            if(d[x]+1==d[e.to] && (f=DFS(e.to, min(a, e.cap-e.flow)))>0){
                e.flow += f;
                edges[G[x][i]^1].flow -= f;
                flow += f;
                a -= f;
                if(a == 0) break;
            }
        }
        return flow;
    }

    int Maxflow(int s, int t){
        this->s = s;  this->t = t;
        int flow = 0;
        while(BFS()){
            memset(cur, 0, sizeof(cur));
            flow += DFS(s, INF);
        }
        return flow;
    }
};
int dis[500][500];
int main()
{
    //freopen("in.txt", "r", stdin);
    int K, C, M;
    while(scanf("%d %d %d", &K, &C, &M) == 3){
        int i, j, k, l, a;
        int sum = K + C;
        for(i = 1;i <= sum;i++){
            for(j = 1;j <= sum;j++){
                scanf("%d", &a);
                if(i==j) { dis[i][j] = 0; continue; }
                if(a == 0) dis[i][j] = INF;
                else dis[i][j] = a;
            }
        }

        for(k = 1;k <= sum;k++){
            for(i = 1;i <= sum;i++){
                for(j = 1;j <= sum;j++){
                    if(dis[i][j] > dis[i][k]+dis[k][j])
                        dis[i][j] = dis[i][k] + dis[k][j];
                }
            }
        }

        int L = 1, R = 40000;
        while(L < R){
            int mid =(L+R)/2;
            Dinic test;
            for(i = 1;i <= K;i++){
                for(j = K+1;j <= sum;j++){
                    if(dis[i][j]<=mid) test.AddEdge(i,j,1);
                }
            }
            for(i = 1;i <= K;i++) test.AddEdge(0,i,M);
            for(i = K+1;i <= sum;i++) test.AddEdge(i,sum+1,1);
            int ans = test.Maxflow(0, sum+1);
            if(ans>=C) {  // why bi_search? it's up
                R = mid;
            }
            else L = mid+1;
        }
        printf("%d\n", R);
    }
    return 0;
}

poj2112,最大流,最优挤奶方案

时间: 2024-10-10 14:50:30

poj2112,最大流,最优挤奶方案的相关文章

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 Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 16550   Accepted: 5945 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) co

poj2112Optimal Milking(最优秀的挤奶方案)——floyd+最大流+二分

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 头奶牛需要走的所有 路程中的最大路程最小.每个测试数据中至少有一个安排方案.每条奶牛到挤奶器有

P3097 [USACO13DEC]最优挤奶(线段树优化dp)

盲猜dp系列... 题意:给定序列,选了i就不能选与i相邻的两个,求最大值,带修改 蒟蒻在考场上10min打完以为只有两种情况的错解...居然能骗一点分... 先讲下当时的思路吧. f[i][0/1]表示第i台选不选的挤奶最大值,两个转移,水得不行. 考完之后在大佬的点播下才明白,这是一个类似独立集的东西. 但是这个数据范围绝对不是让我们跑最大独立集的,毕竟还要修改233... solution: 求和....单点修改...最大值....貌似能想到些什么..... 可爱的线段树..(一点都不可爱

bzoj4094 &amp;&amp; luogu3097 最优挤奶

题目大意: 给定n个点排成一排,每个点有一个点权,有m次修改,每次改变某个点的点权并将最大点独立集计入答案,输出最终的答案 其中\(n\le 40000\ , \ m\le 50000\) QWQ说实话,一开始看这个题,没啥思路呀 后来看了题解才知道是线段树 我们考虑对一个区间,我们只需要关心左右节点是否取,就可以从小的区间更新大区间. 从而实现线段树的区间合并了 QWQ我们定义 \(f[i].both\)表示左右边界都取 \(f[i].left\)表示只取左边界 \(f[i].right\)表

《最优的购书方案》

问题描述:对编号不同的五本书进行购买,其中单买一本8元,买不同编号的两本书享受5%的折扣,不同编号的三本书享受10%的折扣,不同编号的四本书享受20%的折扣,不同编号的五本书享受25%的折扣,注意买同种编号的书不享受折扣优惠:根据顾客提供的买书量,为顾客设计最优的购书方案,以便以最低的价格买到想要的数量. 设计思想:通过对买10本书以内的方案设计后,得出其最优方案的规律是除了买8本是例外之外,其余的最优方案均是买全套书的整数倍再加上另单独购买买书量对整套书的本数求余后所得余数组合后即可. 源代码

购书打折最优方案

题目:书店针对<哈利波特>系列书籍进行促销活动,一共5卷,用编号0.1.2.3.4表示,单独一卷售价8元, 具体折扣如下所示: 本数                  折扣                                   2                       5%                                   3                       10%                                   4    

【Postgresql】postgresql9.3.9版本基于流复制方式双机热备方案

系统环境:centos6.5数据库版本: postgres9.3.9虚拟机2台:Master:10.0.2.160Slave:10.0.2.69数据存储位置:/usr/local/pgsql/data/ 安装pgsql数据库 安装过程可参考我上一篇博客:http://blog.51cto.com/13632960/2117902 两台机器都需要安装完成,我在做热备的时候,Master数据库开启,Slave关闭. 创建流复制用户 Master端进入数据库并执行: CREATE USER repus

SQL Server调优系列基础篇(并行运算总结)

原文:SQL Server调优系列基础篇(并行运算总结) 前言 上三篇文章我们介绍了查看查询计划的方式,以及一些常用的连接运算符.联合运算符的优化技巧. 本篇我们分析SQL Server的并行运算,作为多核计算机盛行的今天,SQL Server也会适时调整自己的查询计划,来适应硬件资源的扩展,充分利用硬件资源,最大限度的提高性能. 闲言少叙,直接进入本篇的正题. 技术准备 同前几篇一样,基于SQL Server2008R2版本,利用微软的一个更简洁的案例库(Northwind)进行解析. 一.并