题意:

      有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. golang调用shell命令(实时输出, 终止等)

    背景 是这样的,最近在研究一个定时任务系统的改造,可能有点像jenkins做到的那种吧. 可以输入shell命令,也可以执行py脚本等等,相比之前来说,也要能够及时停止! 但是遇到了这么个问题,gol ...

  2. 进阶宝典一|SqlServer数据库自动备份设置

    很多人都没机会接触到数据库备份,经常操作的要么是数据库管理员,要么是项目负责人.那是不是说数据库备份就不用学了? 不,其实作为开发人员应该要了解数据备份,数据备份的手段有很多:软件备份.脚本备份.其他 ...

  3. 客官,.NETCore无代码侵入的模型验证了解下

    背景 .NETCore下的模型验证相信绝大部分的.NET开发者或多或少的都用过,微软官方提供的模型验证相关的类位于System.ComponentModel.DataAnnotations命令空间下, ...

  4. 一文搞懂 this、apply、call、bind

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

  5. Fcitx5 上线 FreeBSD

    Fcitx5 上线 FreeBSD textproc/fcitx5textproc/fcitx5-qttextproc/fcitx5-gtktextproc/fcitx5-configtoolchin ...

  6. Nacos常用配置

    属性配置 1. 配置年级是否显示 这里配置的屏蔽的年级,在运营后台去删掉相关id就行了 2. 过滤标签显示特定课程数据 指定 yaml 文件显示 course.tagCourse.tagName=寒假 ...

  7. python学习之类的装饰器进阶版

    装饰器可以修饰函数,同样,也可以修饰类 装饰器 def deco(func):    print('======>被修饰的')return func 装饰器装饰函数的方式,语法糖 @decode ...

  8. 数据搬运组件:基于Sqoop管理数据导入和导出

    本文源码:GitHub || GitEE 一.Sqoop概述 Sqoop是一款开源的大数据组件,主要用来在Hadoop(Hive.HBase等)与传统的数据库(mysql.postgresql.ora ...

  9. 10、字典dict

    字典(dict) 字典是有序,键不重复,元素只能是键值对的可变的容器 dict = {'k1':'v1','k2':'v2'} 容器 元素必须键值对 键不重复,重复则会被覆盖 data = {'k1' ...

  10. C++如何解析函数调用

    C语言是一个简单的语言.用户针对每一个函数,只能设置一个唯一的函数签名.但是C++而言,就给了我们很多的灵活性: 你可以将多个函数设置为相同的名字(overloading) 你可以使用内置操作符重载( ...