题意:

      有n个猪圈,每个猪圈里面都有一定数量的猪(可能大于当前猪圈的数量),每个猪圈都有自己的容量,猪圈与猪圈之间给出了距离,然后突然下雨了,问多久之后所有的猪都能进圈。

思路:

       先跑一遍Floyd求出任意两点之间的最短距离,对于时间,也就是答案,我们可以二分去找,然后对于每次二分,我们可以用DINIC去判断是否满足要求,建图的时候记得拆点,一开始我感觉不用抄点,但是都敲完了,发现不行,又重新建图了,拆成二分图,然后根据当前二分的值连边。。。这个题比较简单,没啥难点,就是长时间没写了,练练手,还有提醒一点,二分的时候可以不直接二分时间,我们可以吧所有可能的时间都找出来,排序,离散化一下,这样直接二分下标,减少时间开销(直接不离散化目测也行,但是离散化能更快点)。下面是我的代码,用的方法是
Floyd+离散化+二分+DINIC做的,这个题思路不难,就是练练手,就解释这么多。

      

#include<queue>

#include<stdio.h>

#include<string.h>

#include<algorithm>

#define N_node 400 + 10

#define N_edge (200 * 200 + 400) * 2 + 100

#define INF 2000000000

#define III 0x3f3f3f3f3f3f3f3f

using namespace std;

typedef struct

{

    int to ,cost ,next;

}STAR;

typedef struct

{

    int x ,t;

}DEP;

DEP xin ,tou;

STAR E[N_edge];

int list[N_node] ,listt[N_node] ,tot;

int deep[N_node];

long long map[202][202];

long long tmp[50000] ,num[50000];

int L[202] ,R[202];

int S;

void add(int a ,int b ,int c)

{

    E[++tot].to = b;

    E[tot].cost = c;

    E[tot].next = list[a];

    list[a] = tot;

    E[++tot].to = a;

    E[tot].cost = 0;

    E[tot].next = list[b];

    list[b] = tot;

}

int minn(int x ,int y)

{

    return x < y ? x : y;

}

void Floyd(int n)

{

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

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

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

    if(map[i][j] > map[i][k] + map[k][j])

    map[i][j] = map[i][k] + map[k][j];

}

bool BFS_Deep(int s ,int t ,int n)

{

    memset(deep ,255 ,sizeof(deep));

    deep[s] = 0;

    xin.x = s ,xin.t = 0;

    queue<DEP>q;

    q.push(xin);

    while(!q.empty())

    {

        tou = q.front();

        q.pop();

        for(int k = list[tou.x] ;k ;k = E[k].next)

        {

            xin.x = E[k].to;

            xin.t = tou.t + 1;

            if(deep[xin.x] != -1 || !E[k].cost)

            continue;

            deep[xin.x] = xin.t;

            q.push(xin);

        }

    }

    for(int i = 0 ;i <= n ;i ++)

    listt[i] = list[i];

    return deep[t] != -1;

}

int DFS_Flow(int s ,int t ,int flow)

{

    if(s == t) return flow;

    int nowflow = 0;

    for(int k = listt[s] ;k ;k = E[k].next)

    {

        listt[s] = k;

        int to = E[k].to;

        int c = E[k].cost;

        if(deep[to] != deep[s] + 1 || !c)

        continue;

        int tmp = DFS_Flow(to ,t ,minn(c ,flow - nowflow));

        nowflow += tmp;

        E[k].cost -= tmp;

        E[k^1].cost += tmp;

        if(flow == nowflow) break;

    }

    if(!nowflow) deep[s] = 0;

    return nowflow;

}

int DINIC(int s ,int t ,int n)

{

    int Ans = 0;

    while(BFS_Deep(s ,t ,n))

    {

        Ans += DFS_Flow(s ,t ,INF);

    }

    return Ans;

}

void Buid(int n ,long long mid)

{

    memset(list ,0 ,sizeof(list)) ,tot = 1;

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

    add(0 ,i ,L[i]) ,add(i + n ,n + n + 1 ,R[i]);

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

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

    if(map[i][j] <= mid) add(i ,j + n ,INF);

}

long long solve(int n)

{

    int t = 0;

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

    for(int j = i ;j <= n ;j ++)

    if(map[i][j] != III) tmp[++t] = map[i][j];

    sort(tmp + 1 ,tmp + t + 1);

    int numn = 0;

    for(int i = 1 ;i <= t ;i ++)

    if(i == 1 || tmp[i] != tmp[i-1])

    num[++numn] = tmp[i];

    int low = 1 ,up = numn ,mid;

    long long Ans = -1;

    while(low <= up)

    {

        mid = (low + up) >> 1;

        Buid(n ,num[mid]);

        if(DINIC(0 ,n + n + 1 ,n + n + 1) == S)

        {

            Ans = num[mid];

            up = mid - 1;

        }else low = mid + 1;

    }

    return Ans;

}

int main ()

{

    int n ,m ,i ,j;

    long long a ,b ,c;

    while(~scanf("%d %d" ,&n ,&m))

    {

        for(S = 0 ,i = 1 ;i <= n ;i ++)

        {

            scanf("%d %d" ,&L[i] ,&R[i]);

            S += L[i];

        }

        for(i = 1 ;i <= n ;i ++)

        {

            for(j = i + 1;j <= n ;j ++)

            map[i][j] = map[j][i] = III;

            map[i][i] = 0;

        }

        for(i = 1 ;i <= m ;i ++)

        {

            scanf("%lld %lld %lld" ,&a ,&b ,&c);

            if(map[a][b] > c) map[a][b] = map[b][a] = c;

        }

        Floyd(n);

        long long Ans = solve(n);

        printf("%lld\n" ,Ans);

    }

    return 0;

}

POJ2391 Floyd+离散化+二分+DINIC的更多相关文章

  1. poj 2391 Ombrophobic Bovines, 最大流, 拆点, 二分, dinic, isap

    poj 2391 Ombrophobic Bovines, 最大流, 拆点, 二分 dinic /* * Author: yew1eb * Created Time: 2014年10月31日 星期五 ...

  2. [Codeforces 1199C]MP3(离散化+二分答案)

    [Codeforces 1199C]MP3(离散化+二分答案) 题面 给出一个长度为n的序列\(a_i\)和常数I,定义一次操作[l,r]可以把序列中<l的数全部变成l,>r的数全部变成r ...

  3. Optimal Milking(POJ2112+二分+Dinic)

    题目链接:http://poj.org/problem?id=2112 题目: 题意:有k台挤奶机,c头奶牛,每台挤奶机每天最多生产m的奶,给你每个物品到其他物品的距离(除了物品到自己本省的距离为0外 ...

  4. hdu 4400 离散化+二分+BFS(暴搜剪枝还超时的时候可以借鉴一下)

    Mines Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Subm ...

  5. POJ 3189 二分+Dinic

    题意: 思路: 二分跨度 枚举最低座次 建图:源点向每头牛连边权为1的边 每头牛向当前枚举的B的区间这段连上边权为1的边 所有座次向汇点连边权为牛棚容量的边 判判流量是不是等于n 一开始写得是直接枚举 ...

  6. 2019 Multi-University Training Contest 3 Find the answer (离散化+二分+树状数组)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6609 题目大意:给定一个含有n个数的序列,还有一个m,对于每个i(1<=i<=n)求出最少 ...

  7. 2019牛客暑期多校训练营(第七场)E-Find the median(思维+树状数组+离散化+二分)

    >传送门< 题意:给n个操作,每次和 (1e9范围内)即往数组里面插所有 的所有数,求每次操作后的中位数思路:区间离散化然后二分答案,因为小于中位数的数字恰好有个,这显然具有单调性.那么问 ...

  8. Codeforces Round #521 (Div. 3) E. Thematic Contests (离散化,二分)

    题意:有\(n\)个话题,每次都必须选取不同的话题,且话题数必须是上次的两倍,第一次的话题数可以任意,问最多能选取多少话题数. 题解:我们首先用桶来记录不同话题的数量,因为只要求话题的数量,与话题是多 ...

  9. nyoj-310-河南省第四届省赛题目-二分+dinic

    SECRET 时间限制:3000 ms  |  内存限制:65535 KB 难度:6   描述 Dr.Kong is constructing a new machine and wishes to ...

随机推荐

  1. NodeJs 入门到放弃 — 网络服务器(三)

    码文不易啊,转载请带上本文链接呀,感谢感谢 https://www.cnblogs.com/echoyya/p/14484454.html 目录 码文不易啊,转载请带上本文链接呀,感谢感谢 https ...

  2. 面向青铜的java自学路线

    有经验的人都知道,java还是需要一些路线的,因为java有些知识前后关联挺大的,先学后面和先学前面难度是不一样的. 如果你是新手,只要你知道路线这个东西,起码要比别人强,至少知道可以怎么走(更重要的 ...

  3. Elasticsearch 模块 - Shard Allocation 机制

    原文 1. 背景 shard allocation 意思是分片分配, 是一个将分片分配到节点的过程; 可能发生该操作的过程包括: 初始恢复(initial recovery) 副本分配(replica ...

  4. 漏洞复现-CVE-2017-12629-RCE-solr:XXE

                  0x00 实验环境 攻击机:Win 10.Win Server 2012 R2 靶机:Ubuntu18 (docker搭建的vulhub靶场) 0x01 影响版本 Apac ...

  5. 关于个Base64,MD5,16进制的转换

    1,待签名数据以UTF-8的格式转字节流,对字节流进行MD5算法得到的签名字节流,再转换为16进制字符串,即生成了数字签名. byte[] targetData = md5.ComputeHash(S ...

  6. Java线程安全问题

    线程安全问题是一个老生常谈的问题,那么多线程环境下究竟有那些问题呢?这么说吧,问题的形式多种多样的,归根结底的说是共享资源问题,无非可见性与有序性问题. 1. 可见性 可见性是对于内存中的共享资源来说 ...

  7. Django常见问题集锦

    1. 解决pycharm终端/cmd运行python脚本报错"ImportError/ModuleNotFoundError:No Module named ..." 问题 项目结 ...

  8. 手把手教你DNS劫持挂马

    出品|MS08067实验室(www.ms08067.com) 本文作者:BlackCat(Ms08067内网安全小组成员) 首先学习DNS劫持之前,务必要了解下DNS是个什么玩意. DNS(域名系统) ...

  9. ElementUI Tree控件在懒加载模式下的重新加载和模糊查询

    之所以使用懒加载是为了提高性能,而且只有在懒加载模式下默认会给所有显示节点设置展开按钮.leaf也可以做到,但是要操作数据比较麻烦. 要实现懒加载模式下的模糊查询以及重新加载必须要使用data与laz ...

  10. 基于sklearn的波士顿房价预测_线性回归学习笔记

    > 以下内容是我在学习https://blog.csdn.net/mingxiaod/article/details/85938251 教程时遇到不懂的问题自己查询并理解的笔记,由于sklear ...